diff options
author | Wei-Ning Huang <w@dexon.org> | 2019-04-11 18:32:33 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@byzantine-lab.io> | 2019-06-15 22:09:55 +0800 |
commit | 21ac6a5ed287112f685174b482d36392c594f0e8 (patch) | |
tree | f36d198fdee235aac353ae32b8d927890bcae060 | |
parent | 67637a63cab266b30d2a634bb8039bd7ff1ae335 (diff) | |
download | go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.tar go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.tar.gz go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.tar.bz2 go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.tar.lz go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.tar.xz go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.tar.zst go-tangerine-21ac6a5ed287112f685174b482d36392c594f0e8.zip |
vendor: use BLS-12_384 curve and update dependencies (#356)
171 files changed, 24751 insertions, 1268 deletions
diff --git a/Dockerfile b/Dockerfile index 01490d5b8..89bf55ecc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,15 @@ FROM golang:1.12-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers g++ gmp-dev openssl-dev pkgconfig +RUN apk add --no-cache make gcc musl-dev linux-headers g++ gmp-dev pkgconfig ADD . /dexon -RUN cd /dexon && make clean && DOCKER=alpine make gdex all +RUN cd /dexon && make clean-cgo && DOCKER=alpine make gdex +RUN cd /dexon && build/env.sh go build -o build/bin/bootnode ./cmd/bootnode # Pull Gdex into a second stage deploy alpine container FROM alpine:latest -RUN apk add --no-cache ca-certificates libstdc++ curl gmp openssl +RUN apk add --no-cache ca-certificates curl COPY --from=builder /dexon/build/bin/gdex /usr/local/bin/ COPY --from=builder /dexon/build/bin/bootnode /usr/local/bin/ diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 9c85a8802..1809f797d 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -1,7 +1,7 @@ # Build Geth in a stock Go builder container FROM golang:1.12-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers g++ gmp-dev openssl-dev pkgconfig +RUN apk add --no-cache make gcc musl-dev linux-headers g++ gmp-dev pkgconfig ADD . /dexon RUN cd /dexon && make clean && DOCKER=alpine make all @@ -9,7 +9,6 @@ RUN cd /dexon && make clean && DOCKER=alpine make all # Pull all binaries into a second stage deploy alpine container FROM alpine:latest -RUN apk add --no-cache ca-certificates libstdc++ gmp openssl COPY --from=builder /dexon/build/bin/* /usr/local/bin/ EXPOSE 8545 8546 30303 30303/udp @@ -41,14 +41,16 @@ lint: ## Run linters. build/env.sh go run build/ci.go lint libbls: - make -C vendor/github.com/dexon-foundation/bls lib/libbls384.a + make -C vendor/github.com/dexon-foundation/bls MCL_USE_OPENSSL=0 lib/libbls384.a -clean: - ./build/clean_go_build_cache.sh - rm -fr build/_workspace/pkg/ $(GOBIN)/* +clean-cgo: make -C vendor/github.com/dexon-foundation/bls clean make -C vendor/github.com/dexon-foundation/mcl clean +clean: clean-cgo + ./build/clean_go_build_cache.sh + rm -fr build/_workspace/pkg/ $(GOBIN)/* + # The devtools target installs tools required for 'go generate'. # You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'. diff --git a/vendor/github.com/dexon-foundation/bls/.gitignore b/vendor/github.com/dexon-foundation/bls/.gitignore new file mode 100644 index 000000000..dacdfc906 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/.gitignore @@ -0,0 +1,7 @@ +CVS +bin/*.exe +lib/*.a +lib/*.so +lib/*.dylib +obj/*.d +obj/*.o diff --git a/vendor/github.com/dexon-foundation/bls/.travis.yml b/vendor/github.com/dexon-foundation/bls/.travis.yml new file mode 100644 index 000000000..71a667a2e --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/.travis.yml @@ -0,0 +1,39 @@ +sudo: true +dist: xenial +services: +- docker +env: + global: + - IMAGE_TAG=dexonfoundation/bls-go-alpine + - DOCKER_USER=spiderpowadeploy + - secure: mqNCngWukyjE3UARxaPjqS0xgC1dsnWfmPhpH2mq7nR6S2cGfJ3xBfyiTS//Clz//7sAL+Tp62r3fxyMjDogrSHZUUssCAwf17RM6vnALqaVbc3wXcTNudiDB5cVKe9C9gZqn1Ivd+qbmtuCezSrOG5Xih1gh4bPTyiFvU1sp9C2icMHkJZkjsP0QqCbHlQrMeECSIPlEGIOXUUSp+WmrZAdi2rHezKeZxuaT73RX1+N/+1RfWXo2MR4ydQU3eALl5s5UA9JweQO+MYIVr8EEpGNqJRYUyURx/5G/Sy2v6Z3imUvXZv1J5aplW/UDls92Olla1JHuvFW6ptRO+PHITNwvEkhxPFj+HcOpqEuSISsdk9rkHUrM0wEYPv6A4vQPUjMHrLQs2tQShVCelM1HtNvDDjttKMmVyRLusFP9eS7uvmmXu2l6efJjsMSFkY5WKbu2U0MQ1j708KH9k2WunU6sjJ+b74PkkZVtkQMIqgTokC0IOqbbrnwh4I9PpVpHAQrewRimMH+lDHk+HlMUCWk7/IcIFUl+mh6RzW2vkZTTr2ctSBI6QzK5smdPmqQpp2lqkGv/hQCBp5ICzFSkU6Djqe3hG8ta3+/Zhi10fPU2HcHDi+gR79CG8dvy+iOeTS2csXZx+YoN2BVkfu9AnrjZ9Kjkf9BMay4CehBUWE= +language: cpp +compiler: +- gcc +- clang +addons: + apt: + packages: + - libgmp-dev +install: +- git clone --depth 1 https://github.com/dexon-foundation/mcl.git $TRAVIS_BUILD_DIR/../mcl +script: +- make -j3 +- make test_ci DISABLE_THREAD_TEST=1 +- make test_go +- env LD_LIBRARY_PATH=../mcl/lib bin/bls_c384_test.exe +- make clean && make -C ../mcl clean +- make -j3 MCL_USE_OPENSSL=0 +- make test_ci DISABLE_THREAD_TEST=1 MCL_USE_OPENSSL=0 +- docker build --tag "$IMAGE_TAG" . -f images/bls-go-alpine/Dockerfile --no-cache +before_deploy: +- echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin +- git_commit="$(git rev-parse --short HEAD)" +- docker tag "$IMAGE_TAG" "${IMAGE_TAG}:${git_commit}" +- docker tag "$IMAGE_TAG" "${IMAGE_TAG}:latest" +deploy: + provider: script + script: docker push "${IMAGE_TAG}:latest" && docker push "${IMAGE_TAG}:${git_commit}" + on: + branch: dev + condition: "$CC = gcc" diff --git a/vendor/github.com/dexon-foundation/bls/CMakeLists.txt b/vendor/github.com/dexon-foundation/bls/CMakeLists.txt new file mode 100644 index 000000000..30fb90fd5 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required (VERSION 2.6) +project(bls CXX ASM) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +set(LIBS mcl gmp) + +include_directories(include/) + +add_library(bls_c256 SHARED src/bls_c256.cpp) +add_library(bls_c384 SHARED src/bls_c384.cpp) +add_library(bls_c384_256 SHARED src/bls_c384_256.cpp) +target_link_libraries(bls_c256 ${LIBS}) +target_link_libraries(bls_c384 ${LIBS}) +target_link_libraries(bls_c384_256 ${LIBS}) + +file(GLOB BLS_HEADERS include/bls/bls.h include/bls/bls.hpp) + +install(TARGETS bls_c256 DESTINATION lib) +install(TARGETS bls_c384 DESTINATION lib) +install(TARGETS bls_c384_256 DESTINATION lib) +install(FILES ${BLS_HEADERS} DESTINATION include/bls) + +set(TEST_LIBS pthread gmpxx) + +add_executable(bls_c256_test test/bls_c256_test.cpp) +target_link_libraries(bls_c256_test bls_c256 ${TEST_LIBS}) +add_executable(bls_c384_test test/bls_c384_test.cpp) +target_link_libraries(bls_c384_test bls_c384 ${TEST_LIBS}) +add_executable(bls_c384_256_test test/bls_c384_256_test.cpp) +target_link_libraries(bls_c384_256_test bls_c384_256 ${TEST_LIBS}) diff --git a/vendor/github.com/dexon-foundation/bls/Makefile b/vendor/github.com/dexon-foundation/bls/Makefile index 556f625ec..efea22274 100644 --- a/vendor/github.com/dexon-foundation/bls/Makefile +++ b/vendor/github.com/dexon-foundation/bls/Makefile @@ -1,55 +1,73 @@ -include ../mcl/common.mk +ifeq ($(findstring MINGW64,$(shell uname -s)),MINGW64) + # cgo accepts not '/c/path' but 'c:/path' + PWD=$(shell pwd|sed s'@^/\([a-z]\)@\1:@') +else + PWD=$(shell pwd) +endif +MCL_DIR?=$(PWD)/../mcl +include $(MCL_DIR)/common.mk LIB_DIR=lib OBJ_DIR=obj EXE_DIR=bin CFLAGS += -std=c++11 LDFLAGS += -lpthread -SRC_SRC=bls_c256.cpp bls_c384.cpp -TEST_SRC=bls256_test.cpp bls384_test.cpp bls_c256_test.cpp bls_c384_test.cpp +SRC_SRC=bls_c256.cpp bls_c384.cpp bls_c384_256.cpp +TEST_SRC=bls256_test.cpp bls384_test.cpp bls384_256_test.cpp bls_c256_test.cpp bls_c384_test.cpp bls_c384_256_test.cpp SAMPLE_SRC=bls256_smpl.cpp bls384_smpl.cpp -CFLAGS+=-I../mcl/include -I./ +CFLAGS+=-I$(MCL_DIR)/include ifneq ($(MCL_MAX_BIT_SIZE),) CFLAGS+=-DMCL_MAX_BIT_SIZE=$(MCL_MAX_BIT_SIZE) endif ifeq ($(DISABLE_THREAD_TEST),1) CFLAGS+=-DDISABLE_THREAD_TEST endif - -SHARE_BASENAME_SUF?=_dy +ifeq ($(BLS_SWAP_G),1) + CFLAGS+=-DBLS_SWAP_G +endif BLS256_LIB=$(LIB_DIR)/libbls256.a BLS384_LIB=$(LIB_DIR)/libbls384.a -BLS256_SNAME=bls256$(SHARE_BASENAME_SUF) -BLS384_SNAME=bls384$(SHARE_BASENAME_SUF) +BLS384_256_LIB=$(LIB_DIR)/libbls384_256.a +BLS256_SNAME=bls256 +BLS384_SNAME=bls384 +BLS384_256_SNAME=bls384_256 BLS256_SLIB=$(LIB_DIR)/lib$(BLS256_SNAME).$(LIB_SUF) BLS384_SLIB=$(LIB_DIR)/lib$(BLS384_SNAME).$(LIB_SUF) -all: $(BLS256_LIB) $(BLS256_SLIB) $(BLS384_LIB) $(BLS384_SLIB) +BLS384_256_SLIB=$(LIB_DIR)/lib$(BLS384_256_SNAME).$(LIB_SUF) +all: $(BLS256_LIB) $(BLS256_SLIB) $(BLS384_LIB) $(BLS384_SLIB) $(BLS384_256_LIB) $(BLS384_256_SLIB) -MCL_LIB=../mcl/lib/libmcl.a +MCL_LIB=$(MCL_DIR)/lib/libmcl.a $(MCL_LIB): - $(MAKE) -C ../mcl lib/libmcl.a + $(MAKE) -C $(MCL_DIR) -$(BLS256_LIB): $(OBJ_DIR)/bls_c256.o +$(BLS256_LIB): $(OBJ_DIR)/bls_c256.o $(MCL_LIB) $(AR) $@ $< $(BLS384_LIB): $(OBJ_DIR)/bls_c384.o $(MCL_LIB) $(AR) $@ $< +$(BLS384_256_LIB): $(OBJ_DIR)/bls_c384_256.o $(MCL_LIB) + $(AR) $@ $< ifneq ($(findstring $(OS),mac/mingw64),) - BLS256_SLIB_LDFLAGS+=-lgmpxx -lgmp -lcrypto -lstdc++ - BLS384_SLIB_LDFLAGS+=-lgmpxx -lgmp -lcrypto -lstdc++ + COMMON_LIB=$(GMP_LIB) $(OPENSSL_LIB) -lstdc++ + BLS256_SLIB_LDFLAGS+=$(COMMON_LIB) + BLS384_SLIB_LDFLAGS+=$(COMMON_LIB) + BLS384_256_SLIB_LDFLAGS+=$(COMMON_LIB) endif ifeq ($(OS),mingw64) - CFLAGS+=-I../mcl + CFLAGS+=-I$(MCL_DIR) BLS256_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(BLS256_SNAME).a BLS384_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(BLS384_SNAME).a + BLS384_256_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(BLS384_256_SNAME).a endif $(BLS256_SLIB): $(OBJ_DIR)/bls_c256.o $(MCL_LIB) - $(PRE)$(CXX) -shared -o $@ $< $(MCL_LIB) $(BLS256_SLIB_LDFLAGS) + $(PRE)$(CXX) -shared -o $@ $< -L$(MCL_DIR)/lib -lmcl $(BLS256_SLIB_LDFLAGS) $(LDFLAGS) $(BLS384_SLIB): $(OBJ_DIR)/bls_c384.o $(MCL_LIB) - $(PRE)$(CXX) -shared -o $@ $< $(MCL_LIB) $(BLS384_SLIB_LDFLAGS) + $(PRE)$(CXX) -shared -o $@ $< -L$(MCL_DIR)/lib -lmcl $(BLS384_SLIB_LDFLAGS) $(LDFLAGS) +$(BLS384_256_SLIB): $(OBJ_DIR)/bls_c384_256.o $(MCL_LIB) + $(PRE)$(CXX) -shared -o $@ $< -L$(MCL_DIR)/lib -lmcl $(BLS384_256_SLIB_LDFLAGS) $(LDFLAGS) VPATH=test sample src @@ -58,35 +76,58 @@ VPATH=test sample src $(OBJ_DIR)/%.o: %.cpp $(PRE)$(CXX) $(CFLAGS) -c $< -o $@ -MMD -MP -MF $(@:.o=.d) +$(EXE_DIR)/%384_256_test.exe: $(OBJ_DIR)/%384_256_test.o $(BLS384_256_LIB) $(MCL_LIB) + $(PRE)$(CXX) $< -o $@ $(BLS384_256_LIB) -L$(MCL_DIR)/lib -lmcl $(LDFLAGS) + $(EXE_DIR)/%384_test.exe: $(OBJ_DIR)/%384_test.o $(BLS384_LIB) $(MCL_LIB) - $(PRE)$(CXX) $< -o $@ $(BLS384_LIB) -lmcl -L../mcl/lib $(LDFLAGS) + $(PRE)$(CXX) $< -o $@ $(BLS384_LIB) -L$(MCL_DIR)/lib -lmcl $(LDFLAGS) $(EXE_DIR)/%256_test.exe: $(OBJ_DIR)/%256_test.o $(BLS256_LIB) $(MCL_LIB) - $(PRE)$(CXX) $< -o $@ $(BLS256_LIB) -lmcl -L../mcl/lib $(LDFLAGS) + $(PRE)$(CXX) $< -o $@ $(BLS256_LIB) -L$(MCL_DIR)/lib -lmcl $(LDFLAGS) # sample exe links libbls256.a $(EXE_DIR)/%.exe: $(OBJ_DIR)/%.o $(BLS256_LIB) $(MCL_LIB) - $(PRE)$(CXX) $< -o $@ $(BLS256_LIB) -lmcl -L../mcl/lib $(LDFLAGS) + $(PRE)$(CXX) $< -o $@ $(BLS256_LIB) -L$(MCL_DIR)/lib -lmcl $(LDFLAGS) +ifeq ($(OS),mac) + install_name_tool bin/bls_smpl.exe -change lib/libmcl.dylib $(MCL_DIR)/lib/libmcl.dylib +endif SAMPLE_EXE=$(addprefix $(EXE_DIR)/,$(SAMPLE_SRC:.cpp=.exe)) sample: $(SAMPLE_EXE) TEST_EXE=$(addprefix $(EXE_DIR)/,$(TEST_SRC:.cpp=.exe)) +ifeq ($(OS),mac) + LIBPATH_KEY=DYLD_LIBRARY_PATH +else + LIBPATH_KEY=LD_LIBRARY_PATH +endif +test_ci: $(TEST_EXE) + @sh -ec 'for i in $(TEST_EXE); do echo $$i; env PATH=$$PATH:../mcl/lib $(LIBPATH_KEY)=../mcl/lib LSAN_OPTIONS=verbosity=1 log_threads=1 $$i; done' + $(MAKE) sample_test + test: $(TEST_EXE) @echo test $(TEST_EXE) - @sh -ec 'for i in $(TEST_EXE); do $$i|grep "ctest:name"; done' > result.txt + @sh -ec 'for i in $(TEST_EXE); do env PATH=$$PATH:../mcl/lib $(LIBPATH_KEY)=../mcl/lib $$i|grep "ctest:name"; done' > result.txt @grep -v "ng=0, exception=0" result.txt; if [ $$? -eq 1 ]; then echo "all unit tests succeed"; else exit 1; fi $(MAKE) sample_test sample_test: $(EXE_DIR)/bls_smpl.exe - python bls_smpl.py - -ifeq ($(OS),mac) - MAC_GO_LDFLAGS="-ldflags=-s" -endif -# PATH is for mingw, LD_RUN_PATH is for linux, DYLD_LIBRARY_PATH is for mac -test_go: ffi/go/bls/bls.go ffi/go/bls/bls_test.go $(BLS384_LIB) - cd ffi/go/bls && go test $(MAC_GO_LDFLAGS) . + env PATH=$$PATH:../mcl/lib $(LIBPATH_KEY)=../mcl/lib python bls_smpl.py + +# PATH is for mingw, LD_LIBRARY_PATH is for linux, DYLD_LIBRARY_PATH is for mac +COMMON_LIB_PATH="../../../lib:../../../../mcl/lib" +PATH_VAL=$$PATH:$(COMMON_LIB_PATH) LD_LIBRARY_PATH=$(COMMON_LIB_PATH) DYLD_LIBRARY_PATH=$(COMMON_LIB_PATH) +test_go256: ffi/go/bls/bls.go ffi/go/bls/bls_test.go $(BLS256_LIB) + cd ffi/go/bls && env PATH=$(PATH_VAL) go test -tags bn256 . +test_go384: ffi/go/bls/bls.go ffi/go/bls/bls_test.go $(BLS384_LIB) + cd ffi/go/bls && env PATH=$(PATH_VAL) go test -tags bn384 . +test_go384_256: ffi/go/bls/bls.go ffi/go/bls/bls_test.go $(BLS384_256_LIB) + cd ffi/go/bls && env PATH=$(PATH_VAL) go test -tags bn384_256 . + +test_go: + $(MAKE) test_go256 + $(MAKE) test_go384 + $(MAKE) test_go384_256 EMCC_OPT=-I./include -I./src -I../mcl/include -I./ -Wall -Wextra EMCC_OPT+=-O3 -DNDEBUG @@ -103,12 +144,19 @@ bls-wasm: $(MAKE) ../bls-wasm/bls_c.js clean: - $(RM) $(OBJ_DIR)/*.d $(OBJ_DIR)/*.o $(EXE_DIR)/*.exe $(GEN_EXE) $(ASM_SRC) $(ASM_OBJ) $(LLVM_SRC) $(BLS256_LIB) $(BLS256_SLIB) $(BLS384_LIB) $(BLS384_SLIB) + $(RM) $(OBJ_DIR)/*.d $(OBJ_DIR)/*.o $(EXE_DIR)/*.exe $(GEN_EXE) $(ASM_SRC) $(ASM_OBJ) $(LLVM_SRC) $(BLS256_LIB) $(BLS256_SLIB) $(BLS384_LIB) $(BLS384_SLIB) $(BLS384_256_LIB) $(BLS384_256_SLIB) ALL_SRC=$(SRC_SRC) $(TEST_SRC) $(SAMPLE_SRC) DEPEND_FILE=$(addprefix $(OBJ_DIR)/, $(ALL_SRC:.cpp=.d)) -include $(DEPEND_FILE) +PREFIX?=/usr/local +install: lib/libbls256.a lib/libbls256.$(LIB_SUF) lib/libbls384.a lib/libbls384.$(LIB_SUF) lib/libbls384_256.a lib/libbls384_256.$(LIB_SUF) + $(MKDIR) $(PREFIX)/include/bls + cp -a include/bls/ $(PREFIX)/include/ + $(MKDIR) $(PREFIX)/lib + cp -a lib/libbls256.a lib/libbls256.$(LIB_SUF) lib/libbls384.a lib/libbls384.$(LIB_SUF) lib/libbls384_256.a lib/libbls384_256.$(LIB_SUF) $(PREFIX)/lib/ + .PHONY: test bls-wasm # don't remove these files automatically diff --git a/vendor/github.com/dexon-foundation/bls/bin/.emptydir b/vendor/github.com/dexon-foundation/bls/bin/.emptydir new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/bin/.emptydir diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/App.config b/vendor/github.com/dexon-foundation/bls/ffi/cs/App.config new file mode 100644 index 000000000..8d234373a --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<configuration> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/> + </startup> +</configuration> diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/Properties/AssemblyInfo.cs b/vendor/github.com/dexon-foundation/bls/ffi/cs/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..201222c55 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリã«é–¢ã™ã‚‹ä¸€èˆ¬æƒ…å ±ã¯ä»¥ä¸‹ã®å±žæ€§ã‚»ãƒƒãƒˆã‚’ã¨ãŠã—ã¦åˆ¶å¾¡ã•ã‚Œã¾ã™ã€‚ +// アセンブリã«é–¢é€£ä»˜ã‘られã¦ã„ã‚‹æƒ…å ±ã‚’å¤‰æ›´ã™ã‚‹ã«ã¯ã€ +// ã“れらã®å±žæ€§å€¤ã‚’変更ã—ã¦ãã ã•ã„。 +[assembly: AssemblyTitle("bls256")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("bls256")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible ã‚’ false ã«è¨å®šã™ã‚‹ã¨ã€ãã®åž‹ã¯ã“ã®ã‚¢ã‚»ãƒ³ãƒ–リ内㧠COM コンãƒãƒ¼ãƒãƒ³ãƒˆã‹ã‚‰ +// å‚ç…§ä¸å¯èƒ½ã«ãªã‚Šã¾ã™ã€‚COM ã‹ã‚‰ã“ã®ã‚¢ã‚»ãƒ³ãƒ–リ内ã®åž‹ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ã€ +// ãã®åž‹ã® ComVisible 属性を true ã«è¨å®šã—ã¦ãã ã•ã„。 +[assembly: ComVisible(false)] + +// ã“ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãŒ COM ã«å…¬é–‹ã•ã‚Œã‚‹å ´åˆã€æ¬¡ã® GUID ㌠typelib ã® ID ã«ãªã‚Šã¾ã™ +[assembly: Guid("e9d06b1b-ea22-4ef4-ba4b-422f7625966c")] + +// アセンブリã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±ã¯æ¬¡ã® 4 ã¤ã®å€¤ã§æ§‹æˆã•ã‚Œã¦ã„ã¾ã™: +// +// メジャー ãƒãƒ¼ã‚¸ãƒ§ãƒ³ +// マイナー ãƒãƒ¼ã‚¸ãƒ§ãƒ³ +// ãƒ“ãƒ«ãƒ‰ç•ªå· +// Revision +// +// ã™ã¹ã¦ã®å€¤ã‚’指定ã™ã‚‹ã‹ã€ä¸‹ã®ã‚ˆã†ã« '*' を使ã£ã¦ãƒ“ルドãŠã‚ˆã³ãƒªãƒ“ジョン番å·ã‚’ +// 既定値ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.cs b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.cs new file mode 100644 index 000000000..6bcaf07fb --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.cs @@ -0,0 +1,351 @@ +þ½Ž¿using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace mcl +{ + class BLS + { + public const int BN254 = 0; + public const int BLS12_381 = 5; + + const int IoEcComp = 512; // fixed byte representation + public const int FR_UNIT_SIZE = 4; + public const int FP_UNIT_SIZE = 6; // 4 if bls256.dll is used + public const int COMPILED_TIME_VAR = FR_UNIT_SIZE * 10 + FP_UNIT_SIZE; + + public const int ID_UNIT_SIZE = FR_UNIT_SIZE; + public const int SECRETKEY_UNIT_SIZE = FR_UNIT_SIZE; + public const int PUBLICKEY_UNIT_SIZE = FP_UNIT_SIZE * 3 * 2; + public const int SIGNATURE_UNIT_SIZE = FP_UNIT_SIZE * 3; + + public const int ID_SERIALIZE_SIZE = FR_UNIT_SIZE * 8; + public const int SECRETKEY_SERIALIZE_SIZE = FR_UNIT_SIZE * 8; + public const int PUBLICKEY_SERIALIZE_SIZE = FP_UNIT_SIZE * 8 * 2; + public const int SIGNATURE_SERIALIZE_SIZE = FP_UNIT_SIZE * 8; + + public const string dllName = FP_UNIT_SIZE == 4 ? "bls256.dll" : "bls384_256.dll"; + [DllImport(dllName)] + public static extern int blsInit(int curveType, int compiledTimeVar); + + [DllImport(dllName)] public static extern void blsIdSetInt(ref Id id, int x); + [DllImport(dllName)] public static extern int blsIdSetDecStr(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport(dllName)] public static extern int blsIdSetHexStr(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport(dllName)] public static extern ulong blsIdGetDecStr([Out]StringBuilder buf, ulong maxBufSize, in Id id); + [DllImport(dllName)] public static extern ulong blsIdGetHexStr([Out]StringBuilder buf, ulong maxBufSize, in Id id); + + [DllImport(dllName)] public static extern ulong blsIdSerialize([Out]byte[] buf, ulong maxBufSize, in Id id); + [DllImport(dllName)] public static extern ulong blsSecretKeySerialize([Out]byte[] buf, ulong maxBufSize, in SecretKey sec); + [DllImport(dllName)] public static extern ulong blsPublicKeySerialize([Out]byte[] buf, ulong maxBufSize, in PublicKey pub); + [DllImport(dllName)] public static extern ulong blsSignatureSerialize([Out]byte[] buf, ulong maxBufSize, in Signature sig); + [DllImport(dllName)] public static extern ulong blsIdDeserialize(ref Id id, [In]byte[] buf, ulong bufSize); + [DllImport(dllName)] public static extern ulong blsSecretKeyDeserialize(ref SecretKey sec, [In]byte[] buf, ulong bufSize); + [DllImport(dllName)] public static extern ulong blsPublicKeyDeserialize(ref PublicKey pub, [In]byte[] buf, ulong bufSize); + [DllImport(dllName)] public static extern ulong blsSignatureDeserialize(ref Signature sig, [In]byte[] buf, ulong bufSize); + + [DllImport(dllName)] public static extern int blsIdIsEqual(in Id lhs, in Id rhs); + [DllImport(dllName)] public static extern int blsSecretKeyIsEqual(in SecretKey lhs, in SecretKey rhs); + [DllImport(dllName)] public static extern int blsPublicKeyIsEqual(in PublicKey lhs, in PublicKey rhs); + [DllImport(dllName)] public static extern int blsSignatureIsEqual(in Signature lhs, in Signature rhs); + // add + [DllImport(dllName)] public static extern void blsSecretKeyAdd(ref SecretKey sec, in SecretKey rhs); + [DllImport(dllName)] public static extern void blsPublicKeyAdd(ref PublicKey pub, in PublicKey rhs); + [DllImport(dllName)] public static extern void blsSignatureAdd(ref Signature sig, in Signature rhs); + // hash buf and set + [DllImport(dllName)] public static extern int blsHashToSecretKey(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + /* + set secretKey if system has /dev/urandom or CryptGenRandom + return 0 if success else -1 + */ + [DllImport(dllName)] public static extern int blsSecretKeySetByCSPRNG(ref SecretKey sec); + + [DllImport(dllName)] public static extern void blsGetPublicKey(ref PublicKey pub, in SecretKey sec); + [DllImport(dllName)] public static extern void blsGetPop(ref Signature sig, in SecretKey sec); + + // return 0 if success + [DllImport(dllName)] public static extern int blsSecretKeyShare(ref SecretKey sec, in SecretKey msk, ulong k, in Id id); + [DllImport(dllName)] public static extern int blsPublicKeyShare(ref PublicKey pub, in PublicKey mpk, ulong k, in Id id); + + + [DllImport(dllName)] public static extern int blsSecretKeyRecover(ref SecretKey sec, in SecretKey secVec, in Id idVec, ulong n); + [DllImport(dllName)] public static extern int blsPublicKeyRecover(ref PublicKey pub, in PublicKey pubVec, in Id idVec, ulong n); + [DllImport(dllName)] public static extern int blsSignatureRecover(ref Signature sig, in Signature sigVec, in Id idVec, ulong n); + + [DllImport(dllName)] public static extern void blsSign(ref Signature sig, in SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string m, ulong size); + + // return 1 if valid + [DllImport(dllName)] public static extern int blsVerify(in Signature sig, in PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string m, ulong size); + [DllImport(dllName)] public static extern int blsVerifyPop(in Signature sig, in PublicKey pub); + + ////////////////////////////////////////////////////////////////////////// + // the following apis will be removed + + // mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r + [DllImport(dllName)] public static extern int blsIdSetLittleEndian(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + /* + return written byte size if success else 0 + */ + [DllImport(dllName)] public static extern ulong blsIdGetLittleEndian([Out]StringBuilder buf, ulong maxBufSize, in Id id); + + // return 0 if success + // mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r + [DllImport(dllName)] public static extern int blsSecretKeySetLittleEndian(ref SecretKey sec, [In]byte[] buf, ulong bufSize); + [DllImport(dllName)] public static extern int blsSecretKeySetDecStr(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport(dllName)] public static extern int blsSecretKeySetHexStr(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + /* + return written byte size if success else 0 + */ + [DllImport(dllName)] public static extern ulong blsSecretKeyGetLittleEndian([Out]byte[] buf, ulong maxBufSize, in SecretKey sec); + /* + return strlen(buf) if success else 0 + buf is '\0' terminated + */ + [DllImport(dllName)] public static extern ulong blsSecretKeyGetDecStr([Out]StringBuilder buf, ulong maxBufSize, in SecretKey sec); + [DllImport(dllName)] public static extern ulong blsSecretKeyGetHexStr([Out]StringBuilder buf, ulong maxBufSize, in SecretKey sec); + [DllImport(dllName)] public static extern int blsPublicKeySetHexStr(ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport(dllName)] public static extern ulong blsPublicKeyGetHexStr([Out]StringBuilder buf, ulong maxBufSize, in PublicKey pub); + [DllImport(dllName)] public static extern int blsSignatureSetHexStr(ref Signature sig, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport(dllName)] public static extern ulong blsSignatureGetHexStr([Out]StringBuilder buf, ulong maxBufSize, in Signature sig); + + public static void Init(int curveType = BN254) { + if (!System.Environment.Is64BitProcess) { + throw new PlatformNotSupportedException("not 64-bit system"); + } + int err = blsInit(curveType, COMPILED_TIME_VAR); + if (err != 0) { + throw new ArgumentException("blsInit"); + } + } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct Id + { + private fixed ulong v[ID_UNIT_SIZE]; + public byte[] Serialize() { + byte[] buf = new byte[ID_SERIALIZE_SIZE]; + ulong n = blsIdSerialize(buf, (ulong)buf.Length, this); + if (n == 0) { + throw new ArithmeticException("blsIdSerialize"); + } + return buf; + } + public void Deserialize(byte[] buf) { + ulong n = blsIdDeserialize(ref this, buf, (ulong)buf.Length); + if (n == 0) { + throw new ArithmeticException("blsIdDeserialize"); + } + } + public bool IsEqual(in Id rhs) { + return blsIdIsEqual(this, rhs) != 0; + } + public void SetDecStr(string s) { + if (blsIdSetDecStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsIdSetDecSt:" + s); + } + } + public void SetHexStr(string s) { + if (blsIdSetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsIdSetHexStr:" + s); + } + } + public void SetInt(int x) { + blsIdSetInt(ref this, x); + } + public string GetDecStr() { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsIdGetDecStr(sb, (ulong)sb.Capacity, this); + if (size == 0) { + throw new ArgumentException("blsIdGetDecStr"); + } + return sb.ToString(0, (int)size); + } + public string GetHexStr() { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsIdGetHexStr(sb, (ulong)sb.Capacity, this); + if (size == 0) { + throw new ArgumentException("blsIdGetHexStr"); + } + return sb.ToString(0, (int)size); + } + } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct SecretKey + { + private fixed ulong v[SECRETKEY_UNIT_SIZE]; + public byte[] Serialize() { + byte[] buf = new byte[SECRETKEY_SERIALIZE_SIZE]; + ulong n = blsSecretKeySerialize(buf, (ulong)buf.Length, this); + if (n == 0) { + throw new ArithmeticException("blsSecretKeySerialize"); + } + return buf; + } + public void Deserialize(byte[] buf) { + ulong n = blsSecretKeyDeserialize(ref this, buf, (ulong)buf.Length); + if (n == 0) { + throw new ArithmeticException("blsSecretKeyDeserialize"); + } + } + public bool IsEqual(in SecretKey rhs) { + return blsSecretKeyIsEqual(this, rhs) != 0; + } + public void SetHexStr(string s) { + if (blsSecretKeySetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsSecretKeySetHexStr:" + s); + } + } + public string GetHexStr() { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsSecretKeyGetHexStr(sb, (ulong)sb.Capacity, this); + if (size == 0) { + throw new ArgumentException("mclBnFr_getStr"); + } + return sb.ToString(0, (int)size); + } + public void Add(in SecretKey rhs) { + blsSecretKeyAdd(ref this, rhs); + } + public void SetByCSPRNG() { + blsSecretKeySetByCSPRNG(ref this); + } + public void SetHashOf(string s) { + if (blsHashToSecretKey(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsHashToSecretKey"); + } + } + public PublicKey GetPublicKey() { + PublicKey pub; + blsGetPublicKey(ref pub, this); + return pub; + } + public Signature Sign(string m) { + Signature sig; + blsSign(ref sig, this, m, (ulong)m.Length); + return sig; + } + public Signature GetPop() { + Signature sig; + blsGetPop(ref sig, this); + return sig; + } + } + // secretKey = sum_{i=0}^{msk.Length - 1} msk[i] * id^i + public static SecretKey ShareSecretKey(in SecretKey[] msk, in Id id) { + SecretKey sec; + if (blsSecretKeyShare(ref sec, msk[0], (ulong)msk.Length, id) != 0) { + throw new ArgumentException("GetSecretKeyForId:" + id.ToString()); + } + return sec; + } + public static SecretKey RecoverSecretKey(in SecretKey[] secVec, in Id[] idVec) { + SecretKey sec; + if (blsSecretKeyRecover(ref sec, secVec[0], idVec[0], (ulong)secVec.Length) != 0) { + throw new ArgumentException("Recover"); + } + return sec; + } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct PublicKey + { + private fixed ulong v[PUBLICKEY_UNIT_SIZE]; + public byte[] Serialize() { + byte[] buf = new byte[PUBLICKEY_SERIALIZE_SIZE]; + ulong n = blsPublicKeySerialize(buf, (ulong)buf.Length, this); + if (n == 0) { + throw new ArithmeticException("blsPublicKeySerialize"); + } + return buf; + } + public void Deserialize(byte[] buf) { + ulong n = blsPublicKeyDeserialize(ref this, buf, (ulong)buf.Length); + if (n == 0) { + throw new ArithmeticException("blsPublicKeyDeserialize"); + } + } + public bool IsEqual(in PublicKey rhs) { + return blsPublicKeyIsEqual(this, rhs) != 0; + } + public void SetStr(string s) { + if (blsPublicKeySetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsPublicKeySetStr:" + s); + } + } + public string GetHexStr() { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsPublicKeyGetHexStr(sb, (ulong)sb.Capacity, this); + if (size == 0) { + throw new ArgumentException("blsPublicKeyGetStr"); + } + return sb.ToString(0, (int)size); + } + public void Add(in PublicKey rhs) { + blsPublicKeyAdd(ref this, rhs); + } + public bool Verify(in Signature sig, string m) { + return blsVerify(sig, this, m, (ulong)m.Length) == 1; + } + public bool VerifyPop(in Signature pop) { + return blsVerifyPop(pop, this) == 1; + } + } + // publicKey = sum_{i=0}^{mpk.Length - 1} mpk[i] * id^i + public static PublicKey SharePublicKey(in PublicKey[] mpk, in Id id) { + PublicKey pub; + if (blsPublicKeyShare(ref pub, mpk[0], (ulong)mpk.Length, id) != 0) { + throw new ArgumentException("GetPublicKeyForId:" + id.ToString()); + } + return pub; + } + public static PublicKey RecoverPublicKey(in PublicKey[] pubVec, in Id[] idVec) { + PublicKey pub; + if (blsPublicKeyRecover(ref pub, pubVec[0], idVec[0], (ulong)pubVec.Length) != 0) { + throw new ArgumentException("Recover"); + } + return pub; + } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct Signature + { + private fixed ulong v[SIGNATURE_UNIT_SIZE]; + public byte[] Serialize() { + byte[] buf = new byte[SIGNATURE_SERIALIZE_SIZE]; + ulong n = blsSignatureSerialize(buf, (ulong)buf.Length, this); + if (n == 0) { + throw new ArithmeticException("blsSignatureSerialize"); + } + return buf; + } + public void Deserialize(byte[] buf) { + ulong n = blsSignatureDeserialize(ref this, buf, (ulong)buf.Length); + if (n == 0) { + throw new ArithmeticException("blsSignatureDeserialize"); + } + } + public bool IsEqual(in Signature rhs) { + return blsSignatureIsEqual(this, rhs) != 0; + } + public void SetStr(string s) { + if (blsSignatureSetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsSignatureSetStr:" + s); + } + } + public string GetHexStr() { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsSignatureGetHexStr(sb, (ulong)sb.Capacity, this); + if (size == 0) { + throw new ArgumentException("blsSignatureGetStr"); + } + return sb.ToString(0, (int)size); + } + public void Add(in Signature rhs) { + blsSignatureAdd(ref this, rhs); + } + } + public static Signature RecoverSign(in Signature[] sigVec, in Id[] idVec) { + Signature sig; + if (blsSignatureRecover(ref sig, sigVec[0], idVec[0], (ulong)sigVec.Length) != 0) { + throw new ArgumentException("Recover"); + } + return sig; + } + } +} diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.csproj b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.csproj new file mode 100644 index 000000000..c03afa436 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.csproj @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{E9D06B1B-EA22-4EF4-BA4B-422F7625966D}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>bls</RootNamespace> + <AssemblyName>bls</AssemblyName> + <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.0.0.%2a</ApplicationVersion> + <IsWebBootstrapper>false</IsWebBootstrapper> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> + <TargetFrameworkProfile /> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>..\..\bin\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <DebugType>full</DebugType> + <PlatformTarget>x64</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <LangVersion>7.2</LangVersion> + <Prefer32Bit>false</Prefer32Bit> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + <OutputPath>..\..\bin\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <Optimize>true</Optimize> + <DebugType>pdbonly</DebugType> + <PlatformTarget>x64</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <Prefer32Bit>false</Prefer32Bit> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <LangVersion>7.2</LangVersion> + </PropertyGroup> + <PropertyGroup> + <NoWin32Manifest>true</NoWin32Manifest> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="bls.cs" /> + <Compile Include="bls_test.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include=".NETFramework,Version=v4.5.2"> + <Visible>False</Visible> + <ProductName>Microsoft .NET Framework 4.5.2 %28x86 ãŠã‚ˆã³ x64%29</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>false</Install> + </BootstrapperPackage> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.sln b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.sln new file mode 100644 index 000000000..7c3dfba7b --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bls", "bls.csproj", "{E9D06B1B-EA22-4EF4-BA4B-422F7625966D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E9D06B1B-EA22-4EF4-BA4B-422F7625966D}.Debug|x64.ActiveCfg = Debug|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966D}.Debug|x64.Build.0 = Debug|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966D}.Release|x64.ActiveCfg = Release|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966D}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1935C301-6478-4F82-9587-6A66B531E327} + EndGlobalSection +EndGlobal diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.cs b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.cs new file mode 100644 index 000000000..3ef5fab9a --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.cs @@ -0,0 +1,298 @@ +þ½Ž¿using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace mcl { + class BLS256 { + const int IoEcComp = 512; // fixed byte representation + public const int MCLBN_FR_UNIT_SIZE = 4; + public const int MCLBN_FP_UNIT_SIZE = 4; + public const int MCLBN_COMPILED_TIME_VAR = MCLBN_FR_UNIT_SIZE * 10 + MCLBN_FP_UNIT_SIZE; + [DllImport("bls256.dll")] + public static extern int blsInit(int curve, int compiledTimeVar); + + [DllImport("bls256.dll")] public static extern void blsIdSetInt(ref Id id, int x); + [DllImport("bls256.dll")] public static extern int blsIdSetDecStr(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern int blsIdSetHexStr(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern ulong blsIdGetDecStr([Out]StringBuilder buf, ulong maxBufSize, ref Id id); + [DllImport("bls256.dll")] public static extern ulong blsIdGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref Id id); + + + [DllImport("bls256.dll")] public static extern ulong blsIdSerialize([Out]StringBuilder buf, ulong maxBufSize, ref Id id); + [DllImport("bls256.dll")] public static extern ulong blsSecretKeySerialize([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec); + [DllImport("bls256.dll")] public static extern ulong blsPublicKeySerialize([Out]StringBuilder buf, ulong maxBufSize, ref PublicKey pub); + [DllImport("bls256.dll")] public static extern ulong blsSignatureSerialize([Out]StringBuilder buf, ulong maxBufSize, ref Signature sig); + + [DllImport("bls256.dll")] public static extern int blsIdDeserialize(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern int blsSecretKeyDeserialize(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern int blsPublicKeyDeserialize(ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern int blsSignatureDeserialize(ref Signature sig, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + + [DllImport("bls256.dll")] public static extern int blsIdIsEqual(ref Id lhs, ref Id rhs); + [DllImport("bls256.dll")] public static extern int blsSecretKeyIsEqual(ref SecretKey lhs, ref SecretKey rhs); + [DllImport("bls256.dll")] public static extern int blsPublicKeyIsEqual(ref PublicKey lhs, ref PublicKey rhs); + [DllImport("bls256.dll")] public static extern int blsSignatureIsEqual(ref Signature lhs, ref Signature rhs); + + // add + [DllImport("bls256.dll")] public static extern void blsSecretKeyAdd(ref SecretKey sec, ref SecretKey rhs); + [DllImport("bls256.dll")] public static extern void blsPublicKeyAdd(ref PublicKey pub, ref PublicKey rhs); + [DllImport("bls256.dll")] public static extern void blsSignatureAdd(ref Signature sig, ref Signature rhs); + + // hash buf and set + [DllImport("bls256.dll")] public static extern int blsHashToSecretKey(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + /* + set secretKey if system has /dev/urandom or CryptGenRandom + return 0 if success else -1 + */ + [DllImport("bls256.dll")] public static extern int blsSecretKeySetByCSPRNG(ref SecretKey sec); + + [DllImport("bls256.dll")] public static extern void blsGetPublicKey(ref PublicKey pub, ref SecretKey sec); + [DllImport("bls256.dll")] public static extern void blsGetPop(ref Signature sig, ref SecretKey sec); + + // return 0 if success + [DllImport("bls256.dll")] public static extern int blsSecretKeyShare(ref SecretKey sec, ref SecretKey msk, ulong k, ref Id id); + [DllImport("bls256.dll")] public static extern int blsPublicKeyShare(ref PublicKey pub, ref PublicKey mpk, ulong k, ref Id id); + + + [DllImport("bls256.dll")] public static extern int blsSecretKeyRecover(ref SecretKey sec, ref SecretKey secVec, ref Id idVec, ulong n); + [DllImport("bls256.dll")] public static extern int blsPublicKeyRecover(ref PublicKey pub, ref PublicKey pubVec, ref Id idVec, ulong n); + [DllImport("bls256.dll")] public static extern int blsSignatureRecover(ref Signature sig, ref Signature sigVec, ref Id idVec, ulong n); + + [DllImport("bls256.dll")] public static extern void blsSign(ref Signature sig, ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string m, ulong size); + + // return 1 if valid + [DllImport("bls256.dll")] public static extern int blsVerify(ref Signature sig, ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string m, ulong size); + [DllImport("bls256.dll")] public static extern int blsVerifyPop(ref Signature sig, ref PublicKey pub); + + ////////////////////////////////////////////////////////////////////////// + // the following apis will be removed + + // mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r + [DllImport("bls256.dll")] public static extern int blsIdSetLittleEndian(ref Id id, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + /* + return written byte size if success else 0 + */ + [DllImport("bls256.dll")] public static extern ulong blsIdGetLittleEndian([Out]StringBuilder buf, ulong maxBufSize, ref Id id); + + // return 0 if success + // mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r + [DllImport("bls256.dll")] public static extern int blsSecretKeySetLittleEndian(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern int blsSecretKeySetDecStr(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern int blsSecretKeySetHexStr(ref SecretKey sec, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + /* + return written byte size if success else 0 + */ + [DllImport("bls256.dll")] public static extern ulong blsSecretKeyGetLittleEndian([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec); + /* + return strlen(buf) if success else 0 + buf is '\0' terminated + */ + [DllImport("bls256.dll")] public static extern ulong blsSecretKeyGetDecStr([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec); + [DllImport("bls256.dll")] public static extern ulong blsSecretKeyGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref SecretKey sec); + [DllImport("bls256.dll")] public static extern int blsPublicKeySetHexStr(ref PublicKey pub, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern ulong blsPublicKeyGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref PublicKey pub); + [DllImport("bls256.dll")] public static extern int blsSignatureSetHexStr(ref Signature sig, [In][MarshalAs(UnmanagedType.LPStr)] string buf, ulong bufSize); + [DllImport("bls256.dll")] public static extern ulong blsSignatureGetHexStr([Out]StringBuilder buf, ulong maxBufSize, ref Signature sig); + + public static void Init() + { + const int CurveFp254BNb = 0; + if (!System.Environment.Is64BitProcess) { + throw new PlatformNotSupportedException("not 64-bit system"); + } + int err = blsInit(CurveFp254BNb, MCLBN_COMPILED_TIME_VAR); + if (err != 0) { + throw new ArgumentException("blsInit"); + } + } + + public struct Id { + private ulong v0, v1, v2, v3; + public bool IsEqual(Id rhs) + { + return blsIdIsEqual(ref this, ref rhs) != 0; + } + public void SetDecStr(String s) + { + if (blsIdSetDecStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsIdSetDecSt:" + s); + } + } + public void SetHexStr(String s) + { + if (blsIdSetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsIdSetHexStr:" + s); + } + } + public void SetInt(int x) + { + blsIdSetInt(ref this, x); + } + public string GetDecStr() + { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsIdGetDecStr(sb, (ulong)sb.Capacity, ref this); + if (size == 0) { + throw new ArgumentException("blsIdGetDecStr"); + } + return sb.ToString(0, (int)size); + } + public string GetHexStr() + { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsIdGetHexStr(sb, (ulong)sb.Capacity, ref this); + if (size == 0) { + throw new ArgumentException("blsIdGetHexStr"); + } + return sb.ToString(0, (int)size); + } + } + public struct SecretKey { + private ulong v0, v1, v2, v3; + public bool IsEqual(SecretKey rhs) + { + return blsSecretKeyIsEqual(ref this, ref rhs) != 0; + } + public void SetHexStr(String s) + { + if (blsSecretKeySetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsSecretKeySetHexStr:" + s); + } + } + public string GetHexStr() + { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsSecretKeyGetHexStr(sb, (ulong)sb.Capacity, ref this); + if (size == 0) { + throw new ArgumentException("mclBnFr_getStr"); + } + return sb.ToString(0, (int)size); + } + public void Add(SecretKey rhs) + { + blsSecretKeyAdd(ref this, ref rhs); + } + public void SetByCSPRNG() + { + blsSecretKeySetByCSPRNG(ref this); + } + public void SetHashOf(string s) + { + if (blsHashToSecretKey(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsHashToSecretKey"); + } + } + public PublicKey GetPublicKey() + { + PublicKey pub = new PublicKey(); + blsGetPublicKey(ref pub, ref this); + return pub; + } + public Signature Signature(String m) + { + Signature Signature = new Signature(); + blsSign(ref Signature, ref this, m, (ulong)m.Length); + return Signature; + } + } + // secretKey = sum_{i=0}^{msk.Length - 1} msk[i] * id^i + public static SecretKey ShareSecretKey(SecretKey[] msk, Id id) + { + SecretKey sec = new SecretKey(); + if (blsSecretKeyShare(ref sec, ref msk[0], (ulong)msk.Length, ref id) != 0) { + throw new ArgumentException("GetSecretKeyForId:" + id.ToString()); + } + return sec; + } + public static SecretKey RecoverSecretKey(SecretKey[] secs, Id[] ids) + { + SecretKey sec = new SecretKey(); + if (blsSecretKeyRecover(ref sec, ref secs[0], ref ids[0], (ulong)secs.Length) != 0) { + throw new ArgumentException("Recover"); + } + return sec; + } + public struct PublicKey { + private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11; + private ulong v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23; + public bool IsEqual(PublicKey rhs) + { + return blsPublicKeyIsEqual(ref this, ref rhs) != 0; + } + public void SetStr(String s) + { + if (blsPublicKeySetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsPublicKeySetStr:" + s); + } + } + public string GetHexStr() + { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsPublicKeyGetHexStr(sb, (ulong)sb.Capacity, ref this); + if (size == 0) { + throw new ArgumentException("blsPublicKeyGetStr"); + } + return sb.ToString(0, (int)size); + } + public void Add(PublicKey rhs) + { + blsPublicKeyAdd(ref this, ref rhs); + } + public bool Verify(Signature Signature, string m) + { + return blsVerify(ref Signature, ref this, m, (ulong)m.Length) == 1; + } + } + // publicKey = sum_{i=0}^{mpk.Length - 1} mpk[i] * id^i + public static PublicKey SharePublicKey(PublicKey[] mpk, Id id) + { + PublicKey pub = new PublicKey(); + if (blsPublicKeyShare(ref pub, ref mpk[0], (ulong)mpk.Length, ref id) != 0) { + throw new ArgumentException("GetPublicKeyForId:" + id.ToString()); + } + return pub; + } + public static PublicKey RecoverPublicKey(PublicKey[] pubs, Id[] ids) + { + PublicKey pub = new PublicKey(); + if (blsPublicKeyRecover(ref pub, ref pubs[0], ref ids[0], (ulong)pubs.Length) != 0) { + throw new ArgumentException("Recover"); + } + return pub; + } + public struct Signature { + private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11; + public bool IsEqual(Signature rhs) + { + return blsSignatureIsEqual(ref this, ref rhs) != 0; + } + public void SetStr(String s) + { + if (blsSignatureSetHexStr(ref this, s, (ulong)s.Length) != 0) { + throw new ArgumentException("blsSignatureSetStr:" + s); + } + } + public string GetHexStr() + { + StringBuilder sb = new StringBuilder(1024); + ulong size = blsSignatureGetHexStr(sb, (ulong)sb.Capacity, ref this); + if (size == 0) { + throw new ArgumentException("blsSignatureGetStr"); + } + return sb.ToString(0, (int)size); + } + public void Add(Signature rhs) + { + blsSignatureAdd(ref this, ref rhs); + } + } + public static Signature RecoverSign(Signature[] signs, Id[] ids) + { + Signature Signature = new Signature(); + if (blsSignatureRecover(ref Signature, ref signs[0], ref ids[0], (ulong)signs.Length) != 0) { + throw new ArgumentException("Recover"); + } + return Signature; + } + } +} diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.csproj b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.csproj new file mode 100644 index 000000000..032a1d347 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.csproj @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{E9D06B1B-EA22-4EF4-BA4B-422F7625966C}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>bls256</RootNamespace> + <AssemblyName>bls256</AssemblyName> + <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>..\..\bin\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <AllowUnsafeBlocks>false</AllowUnsafeBlocks> + <DebugType>full</DebugType> + <PlatformTarget>x64</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + <OutputPath>..\..\bin\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <Optimize>true</Optimize> + <DebugType>pdbonly</DebugType> + <PlatformTarget>x64</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="bls256.cs" /> + <Compile Include="bls256_test.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.sln b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.sln new file mode 100644 index 000000000..eb29af97b --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBD}") = "bls256", "bls256.csproj", "{E9D06B1B-EA22-4EF4-BA4B-422F7625966C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E9D06B1B-EA22-4EF4-BA4B-422F7625966C}.Debug|x64.ActiveCfg = Debug|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966C}.Debug|x64.Build.0 = Debug|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966C}.Release|x64.ActiveCfg = Release|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966C}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256_test.cs b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256_test.cs new file mode 100644 index 000000000..989993e0f --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls256_test.cs @@ -0,0 +1,126 @@ +using System; + +namespace mcl { + using static BLS256; + class BLS256Test { + static int err = 0; + static void assert(string msg, bool b) + { + if (b) return; + Console.WriteLine("ERR {0}", msg); + err++; + } + static void TestId() + { + Console.WriteLine("TestId"); + Id id = new Id(); + id.SetDecStr("255"); + assert("GetStr(10)", id.GetDecStr() == "255"); + assert("GetStr(16)", id.GetHexStr() == "ff"); + } + static void TestSecretKey() + { + Console.WriteLine("TestSecretKey"); + SecretKey sec = new SecretKey(); + sec.SetHexStr("ff"); + assert("GetHexStr()", sec.GetHexStr() == "ff"); + { + SecretKey sec2 = new SecretKey(); + sec.SetHexStr("321"); + sec2.SetHexStr("4000"); + sec.Add(sec2); + assert("sec.Add", sec.GetHexStr() == "4321"); + sec.SetByCSPRNG(); + Console.WriteLine("sec.Init={0}", sec.GetHexStr()); + } + } + static void TestPublicKey() + { + Console.WriteLine("TestPublicKey"); + SecretKey sec = new SecretKey(); + sec.SetByCSPRNG(); + PublicKey pub = sec.GetPublicKey(); + String s = pub.GetHexStr(); + Console.WriteLine("pub={0}", s); + PublicKey pub2 = new PublicKey(); + pub2.SetStr(s); + assert("pub.SetStr", pub.IsEqual(pub2)); + } + static void TestSign() + { + Console.WriteLine("TestSign"); + SecretKey sec = new SecretKey(); + sec.SetByCSPRNG(); + PublicKey pub = sec.GetPublicKey(); + String m = "abc"; + Signature sig = sec.Signature(m); + assert("verify", pub.Verify(sig, m)); + assert("not verify", !pub.Verify(sig, m + "a")); + } + static void TestSharing() + { + Console.WriteLine("TestSharing"); + int k = 5; + SecretKey[] msk = new SecretKey[k]; + PublicKey[] mpk = new PublicKey[k]; + // make master secretkey + for (int i = 0; i < k; i++) { + msk[i].SetByCSPRNG(); + mpk[i] = msk[i].GetPublicKey(); + } + int n = 30; + Id[] ids = new Id[n]; + SecretKey[] secs = new SecretKey[n]; + PublicKey[] pubs = new PublicKey[n]; + for (int i = 0; i < n; i++) { + ids[i].SetInt(i * i + 123); + secs[i] = ShareSecretKey(msk, ids[i]); + pubs[i] = SharePublicKey(mpk, ids[i]); + assert("share publicKey", secs[i].GetPublicKey().IsEqual(pubs[i])); + } + string m = "doremi"; + for (int i = 0; i < n; i++) { + Signature Signature = secs[i].Signature(m); + assert("Signature.Verify", pubs[i].Verify(Signature, m)); + } + { + int[] idxTbl = { 0, 2, 5, 8, 10 }; + assert("idxTbl.Length=k", idxTbl.Length == k); + Id[] subIds = new Id[k]; + SecretKey[] subSecs = new SecretKey[k]; + PublicKey[] subPubs = new PublicKey[k]; + Signature[] subSigns = new Signature[k]; + for (int i = 0; i < k; i++) { + int idx = idxTbl[i]; + subIds[i] = ids[idx]; + subSecs[i] = secs[idx]; + subPubs[i] = pubs[idx]; + subSigns[i] = secs[idx].Signature(m); + } + SecretKey sec = RecoverSecretKey(subSecs, subIds); + PublicKey pub = RecoverPublicKey(subPubs, subIds); + assert("check pub", pub.IsEqual(sec.GetPublicKey())); + Signature Signature = RecoverSign(subSigns, subIds); + assert("Signature.verify", pub.Verify(Signature, m)); + } + } + static void Main(string[] args) + { + try { + Init(); + TestId(); + TestSecretKey(); + TestPublicKey(); + TestSign(); + TestSharing(); + if (err == 0) { + Console.WriteLine("all tests succeed"); + } else { + Console.WriteLine("err={0}", err); + } + } catch (Exception e) { + Console.WriteLine("ERR={0}", e); + } + } + } +} diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/bls_test.cs b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls_test.cs new file mode 100644 index 000000000..2eb451ba9 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/bls_test.cs @@ -0,0 +1,176 @@ +using System; + +namespace mcl +{ + using static BLS; + class BLSTest + { + static int err = 0; + static void assert(string msg, bool b) { + if (b) return; + Console.WriteLine("ERR {0}", msg); + err++; + } + static void TestId() { + Console.WriteLine("TestId"); + Id id1; + id1.SetDecStr("255"); + assert("GetStr(10)", id1.GetDecStr() == "255"); + assert("GetStr(16)", id1.GetHexStr() == "ff"); + Id id2; + id2.SetInt(255); + assert("IsEqual", id1.IsEqual(id2)); + } + static void TestSecretKey() { + Console.WriteLine("TestSecretKey"); + SecretKey sec; + sec.SetHexStr("ff"); + assert("GetHexStr()", sec.GetHexStr() == "ff"); + { + SecretKey sec2; + sec.SetHexStr("321"); + sec2.SetHexStr("4000"); + sec.Add(sec2); + assert("sec.Add", sec.GetHexStr() == "4321"); + sec.SetByCSPRNG(); + Console.WriteLine("sec.Init={0}", sec.GetHexStr()); + } + { + SecretKey sec2; + byte[] buf = sec.Serialize(); + sec2.Deserialize(buf); + assert("serialize", sec2.IsEqual(sec)); + } + } + static void TestPublicKey() { + Console.WriteLine("TestPublicKey"); + SecretKey sec; + sec.SetByCSPRNG(); + PublicKey pub = sec.GetPublicKey(); + string s = pub.GetHexStr(); + Console.WriteLine("pub={0}", s); + { + PublicKey pub2; + pub2.SetStr(s); + assert("pub.SetStr", pub.IsEqual(pub2)); + } + { + PublicKey pub2; + byte[] buf = pub.Serialize(); + pub2.Deserialize(buf); + assert("serialize", pub2.IsEqual(pub)); + } + } + static void TestSign() { + Console.WriteLine("TestSign"); + SecretKey sec; + sec.SetByCSPRNG(); + PublicKey pub = sec.GetPublicKey(); + string m = "abc"; + Signature sig = sec.Sign(m); + Console.WriteLine("sig={0}", sig.GetHexStr()); + assert("verify", pub.Verify(sig, m)); + assert("not verify", !pub.Verify(sig, m + "a")); + { + Signature sig2; + byte[] buf = sig.Serialize(); + sig2.Deserialize(buf); + assert("serialize", sig2.IsEqual(sig)); + } + } + static void TestSharing() { + Console.WriteLine("TestSharing"); + int k = 5; + SecretKey[] msk = new SecretKey[k]; + PublicKey[] mpk = new PublicKey[k]; + // make master secretkey + for (int i = 0; i < k; i++) { + msk[i].SetByCSPRNG(); + mpk[i] = msk[i].GetPublicKey(); + } + int n = 30; + Id[] ids = new Id[n]; + SecretKey[] secs = new SecretKey[n]; + PublicKey[] pubs = new PublicKey[n]; + for (int i = 0; i < n; i++) { + ids[i].SetInt(i * i + 123); + secs[i] = ShareSecretKey(msk, ids[i]); + pubs[i] = SharePublicKey(mpk, ids[i]); + assert("share publicKey", secs[i].GetPublicKey().IsEqual(pubs[i])); + } + string m = "doremi"; + for (int i = 0; i < n; i++) { + Signature Signature = secs[i].Sign(m); + assert("Signature.Verify", pubs[i].Verify(Signature, m)); + } + { + int[] idxTbl = { 0, 2, 5, 8, 10 }; + assert("idxTbl.Length=k", idxTbl.Length == k); + Id[] subIds = new Id[k]; + SecretKey[] subSecs = new SecretKey[k]; + PublicKey[] subPubs = new PublicKey[k]; + Signature[] subSigns = new Signature[k]; + for (int i = 0; i < k; i++) { + int idx = idxTbl[i]; + subIds[i] = ids[idx]; + subSecs[i] = secs[idx]; + subPubs[i] = pubs[idx]; + subSigns[i] = secs[idx].Sign(m); + } + SecretKey sec = RecoverSecretKey(subSecs, subIds); + PublicKey pub = RecoverPublicKey(subPubs, subIds); + assert("check pub", pub.IsEqual(sec.GetPublicKey())); + Signature Signature = RecoverSign(subSigns, subIds); + assert("Signature.verify", pub.Verify(Signature, m)); + } + } + static void TestAggregate() { + Console.WriteLine("TestAggregate"); + const int n = 10; + const string m = "abc"; + SecretKey[] secVec = new SecretKey[n]; + PublicKey[] pubVec = new PublicKey[n]; + Signature[] popVec = new Signature[n]; + Signature[] sigVec = new Signature[n]; + for (int i = 0; i < n; i++) { + secVec[i].SetByCSPRNG(); + pubVec[i] = secVec[i].GetPublicKey(); + popVec[i] = secVec[i].GetPop(); + sigVec[i] = secVec[i].Sign(m); + } + SecretKey secAgg; + PublicKey pubAgg; + Signature sigAgg; + for (int i = 0; i < n; i++) { + secAgg.Add(secVec[i]); + assert("verify pop", pubVec[i].VerifyPop(popVec[i])); + pubAgg.Add(pubVec[i]); + sigAgg.Add(sigVec[i]); + } + assert("aggregate sec", secAgg.Sign(m).IsEqual(sigAgg)); + assert("aggregate", pubAgg.Verify(sigAgg, m)); + } + static void Main(string[] args) { + try { + int[] curveTypeTbl = { BN254, BLS12_381 }; + foreach (int curveType in curveTypeTbl) { + Console.WriteLine("curveType={0}", curveType); + Init(curveType); + TestId(); + TestSecretKey(); + TestPublicKey(); + TestSign(); + TestSharing(); + TestAggregate(); + if (err == 0) { + Console.WriteLine("all tests succeed"); + } else { + Console.WriteLine("err={0}", err); + } + } + } catch (Exception e) { + Console.WriteLine("ERR={0}", e); + } + } + } +} diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/readme-ja.md b/vendor/github.com/dexon-foundation/bls/ffi/cs/readme-ja.md new file mode 100644 index 000000000..199135725 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/readme-ja.md @@ -0,0 +1,188 @@ +# BLSç½²åã®C#ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚° + +# å¿…è¦ç’°å¢ƒ + +* Visual Studio 2017(x64) or later +* C# 7.2 or later +* .NET Framework 4.5.2 or later + +# DLLã®ãƒ“ルド方法 + +Visual Studio 2017ã®64bit用コマンドプãƒãƒ³ãƒ—トを開ã„㦠+``` +md work +cd work +git clone https://github.com/herumi/cybozulib_ext +git clone https://github.com/herumi/mcl +git clone https://github.com/herumi/bls +cd bls +mklib dll +``` +`bls/bin/*.dll`ãŒä½œæˆã•ã‚Œã‚‹ã€‚ + +# サンプルã®ãƒ“ルド方法 + +bls/ffi/cs/bls.slnã‚’é–‹ã„ã¦å®Ÿè¡Œã™ã‚‹ã€‚ + +* æ³¨æ„ bls256.slnã¯å¤ã„ãŸã‚使ã‚ãªã„ã§ãã ã•ã„。 + +# クラスã¨API + +## API + +* `Init(int curveType = BN254);` + * ライブラリを曲線curveTypeã§åˆæœŸåŒ–ã™ã‚‹ã€‚ + * curveType = BN254 or BLS12_381 +* `SecretKey ShareSecretKey(in SecretKey[] msk, in Id id);` + * マスター秘密éµã®åˆ—mskã«å¯¾ã™ã‚‹idã®ç§˜å¯†éµã‚’生æˆ(共有)ã™ã‚‹ã€‚ +* `SecretKey RecoverSecretKey(in SecretKey[] secVec, in Id[] idVec);` + * 秘密éµsecVecã¨ID idVecã®ãƒšã‚¢ã‹ã‚‰ç§˜å¯†éµã‚’復元ã™ã‚‹ã€‚ +* `PublicKey SharePublicKey(in PublicKey[] mpk, in Id id);` + * マスター公開éµã®åˆ—mpkã«å¯¾ã™ã‚‹idã®å…¬é–‹éµã‚’生æˆ(共有)ã™ã‚‹ã€‚ +* `PublicKey RecoverPublicKey(in PublicKey[] pubVec, in Id[] idVec);` + * 公開éµpubVecã¨ID idVecã®ãƒšã‚¢ã‹ã‚‰å…¬é–‹éµã‚’復元ã™ã‚‹ã€‚ +* `Signature RecoverSign(in Signature[] sigVec, in Id[] idVec);` + * ç½²åsigVecã¨ID idVecã®ãƒšã‚¢ã‹ã‚‰ç½²åを復元ã™ã‚‹ã€‚ + +## Id + +è˜åˆ¥åクラス + +* `byte[] Serialize();` + * Idをシリアライズã™ã‚‹ã€‚ +* `void Deserialize(byte[] buf);` + * ãƒã‚¤ãƒˆåˆ—bufã‹ã‚‰Idをデシリアライズã™ã‚‹ã€‚ +* `bool IsEqual(in Id rhs);` + * åŒå€¤åˆ¤å®šã€‚ +* `void SetDecStr(string s);` + * 10進数文å—列をè¨å®šã™ã‚‹ã€‚ +* `void SetHexStr(string s);` + * 16進数文å—列をè¨å®šã™ã‚‹ã€‚ +* `void SetInt(int x);` + * æ•´æ•°xã‚’è¨å®šã™ã‚‹ã€‚ +* `string GetDecStr();` + * 10進数表記をå–å¾—ã™ã‚‹ã€‚ +* `string GetHexStr();` + * 16進数表記をå–å¾—ã™ã‚‹ã€‚ + +## SecretKey + +* `byte[] Serialize();` + * Idをシリアライズã™ã‚‹ã€‚ +* `void Deserialize(byte[] buf);` + * ãƒã‚¤ãƒˆåˆ—bufã‹ã‚‰SecretKeyをデシリアライズã™ã‚‹ã€‚ +* `bool IsEqual(in SecretKey rhs);` + * åŒå€¤åˆ¤å®šã€‚ +* `void SetHexStr(string s);` + * 16進数文å—列をè¨å®šã™ã‚‹ã€‚ +* `string GetHexStr();` + * 16進数表記をå–å¾—ã™ã‚‹ã€‚ +* `void Add(in SecretKey rhs);` + * 秘密éµrhsã‚’åŠ ç®—ã™ã‚‹ã€‚ +* `void SetByCSPRNG();` + * æš—å·å¦çš„乱数ã§è¨å®šã™ã‚‹ã€‚ +* `void SetHashOf(string s);` + * æ–‡å—列sã®ãƒãƒƒã‚·ãƒ¥å€¤ã‚’è¨å®šã™ã‚‹ã€‚ +* `PublicKey GetPublicKey();` + * 対応ã™ã‚‹å…¬é–‹éµã‚’å–å¾—ã™ã‚‹ã€‚ +* `Signature Sign(string m);` + * æ–‡å—列mã®ç½²åを生æˆã™ã‚‹ã€‚ +* `Signature GetPop();` + * 自身ã®ç§˜å¯†éµã«ã‚ˆã‚‹ç½²å(Proof Of Posession)を生æˆã™ã‚‹ã€‚ + +## PublicKey + +* `byte[] Serialize();` + * PublicKeyをシリアライズã™ã‚‹ã€‚ +* `void Deserialize(byte[] buf);` + * ãƒã‚¤ãƒˆåˆ—bufã‹ã‚‰PublicKeyをデシリアライズã™ã‚‹ã€‚ +* `bool IsEqual(in PublicKey rhs);` + * åŒå€¤åˆ¤å®šã€‚ +* `void Add(in PublicKey rhs);` + * 公開éµrhsã‚’åŠ ç®—ã™ã‚‹ã€‚ +* `void SetHexStr(string s);` + * 16進数文å—列をè¨å®šã™ã‚‹ã€‚ +* `string GetHexStr();` + * 16進数表記をå–å¾—ã™ã‚‹ã€‚ +* `bool Verify(in Signature sig, string m);` + * æ–‡å—列mã«å¯¾ã™ã‚‹ç½²åsigã®æ£å½“性を確èªã™ã‚‹ã€‚ +* `bool VerifyPop(in Signature pop);` + * PoPã®æ£å½“性を確èªã™ã‚‹ã€‚ + +## Signature + +* `byte[] Serialize();` + * Signatureをシリアライズã™ã‚‹ã€‚ +* `void Deserialize(byte[] buf);` + * ãƒã‚¤ãƒˆåˆ—bufã‹ã‚‰Signatureをデシリアライズã™ã‚‹ã€‚ +* `bool IsEqual(in Signature rhs);` + * åŒå€¤åˆ¤å®šã€‚ +* `void Add(in Signature rhs);` + * ç½²århsã‚’åŠ ç®—ã™ã‚‹ã€‚ +* `void SetHexStr(string s);` + * 16進数文å—列をè¨å®šã™ã‚‹ã€‚ +* `string GetHexStr();` + * 16進数表記をå–å¾—ã™ã‚‹ã€‚ + +## 使ã„æ–¹ + +### 最å°ã‚µãƒ³ãƒ—ル + +``` +using static BLS; + +Init(BN254); // ライブラリåˆæœŸåŒ– +SecretKey sec; +sec.SetByCSPRNG(); // 秘密éµã®åˆæœŸåŒ– +PublicKey pub = sec.GetPublicKey(); // 公開éµã®å–å¾— +string m = "abc"; +Signature sig = sec.Sign(m); // ç½²åã®ä½œæˆ +if (pub.Verify(sig, m))) { + // ç½²åã®ç¢ºèª +} +``` + +### 集約署å +``` +Init(BN254); // ライブラリåˆæœŸåŒ– +const int n = 10; +const string m = "abc"; +SecretKey[] secVec = new SecretKey[n]; +PublicKey[] pubVec = new PublicKey[n]; +Signature[] popVec = new Signature[n]; +Signature[] sigVec = new Signature[n]; + +for (int i = 0; i < n; i++) { + secVec[i].SetByCSPRNG(); // 秘密éµã®åˆæœŸåŒ– + pubVec[i] = secVec[i].GetPublicKey(); // 公開éµã®å–å¾— + popVec[i] = secVec[i].GetPop(); // 所有(PoP)ã®è¨¼æ˜Ž + sigVec[i] = secVec[i].Sign(m); // ç½²å +} + +SecretKey secAgg; +PublicKey pubAgg; +Signature sigAgg; +for (int i = 0; i < n; i++) { + // PoPã®ç¢ºèª + if (pubVec[i].VerifyPop(popVec[i]))) { + // エラー + return; + } + pubAgg.Add(pubVec[i]); // 公開éµã®é›†ç´„ + sigAgg.Add(sigVec[i]); // ç½²åã®é›†ç´„ +} +if (pubAgg.Verify(sigAgg, m)) { + // ç½²åã®ç¢ºèª +} +``` + +# ライセンス + +modified new BSD License +http://opensource.org/licenses/BSD-3-Clause + +# 著者 + +(C)2019 å…‰æˆæ»‹ç”Ÿ MITSUNARI Shigeo(herumi@nifty.com) All rights reserved. +本コンテンツã®è‘—作権ã€ãŠã‚ˆã³æœ¬ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ä¸ã«å‡ºã¦ãる商標権ã€å›£ä½“åã€ãƒã‚´ã€è£½å“〠+サービスãªã©ã¯ãã‚Œãžã‚Œã€å„権利ä¿æœ‰è€…ã«å¸°å±žã—ã¾ã™ diff --git a/vendor/github.com/dexon-foundation/bls/ffi/cs/readme.md b/vendor/github.com/dexon-foundation/bls/ffi/cs/readme.md new file mode 100644 index 000000000..2b7191871 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/cs/readme.md @@ -0,0 +1,185 @@ +# C# binding of BLS threshold signature library + +# Installation Requirements + +* Visual Studio 2017 or later +* C# 7.2 or later +* .NET Framework 4.5.2 or later + +# How to build + +``` +md work +cd work +git clone https://github.com/herumi/cybozulib_ext +git clone https://github.com/herumi/mcl +git clone https://github.com/herumi/bls +cd bls +mklib dll +``` +bls/bin/*.dll are created + +# How to build a sample + +Open bls/ffi/cs/bls.sln and exec it. + +* Remark. bls256 is obsolete. Please use bls.sln. + +# class and API + +## API + +* `Init(int curveType = BN254);` + * initialize this library with a curve `curveType`. + * curveType = BN254 or BLS12_381 +* `SecretKey ShareSecretKey(in SecretKey[] msk, in Id id);` + * generate the shared secret key from a sequence of master secret keys msk and Id. +* `SecretKey RecoverSecretKey(in SecretKey[] secVec, in Id[] idVec);` + * recover the secret key from a sequence of secret keys secVec and idVec. +* `PublicKey SharePublicKey(in PublicKey[] mpk, in Id id);` + * generate the shared public key from a sequence of master public keys mpk and Id. +* `PublicKey RecoverPublicKey(in PublicKey[] pubVec, in Id[] idVec);` + * recover the public key from a sequence of public keys pubVec and idVec. +* `Signature RecoverSign(in Signature[] sigVec, in Id[] idVec);` + * recover the signature from a sequence of signatures siVec and idVec. + +## Id + +Identifier class + +* `byte[] Serialize();` + * serialize Id +* `void Deserialize(byte[] buf);` + * deserialize from byte[] buf +* `bool IsEqual(in Id rhs);` + * equality +* `void SetDecStr(string s);` + * set by a decimal string s +* `void SetHexStr(string s);` + * set by a hexadecimal string s +* `void SetInt(int x);` + * set an integer x +* `string GetDecStr();` + * get a decimal string +* `string GetHexStr();` + * get a hexadecimal string + +## SecretKey + +* `byte[] Serialize();` + * serialize SecretKey +* `void Deserialize(byte[] buf);` + * deserialize from byte[] buf +* `bool IsEqual(in SecretKey rhs);` + * equality +* `string GetDecStr();` + * get a decimal string +* `string GetHexStr();` + * get a hexadecimal string +* `void Add(in SecretKey rhs);` + * add a secret key rhs +* `void SetByCSPRNG();` + * set a secret key by cryptographically secure pseudo random number generator +* `void SetHashOf(string s);` + * set a secret key by a hash of string s +* `PublicKey GetPublicKey();` + * get the corresponding public key to a secret key +* `Signature Sign(string m);` + * sign a string m +* `Signature GetPop();` + * get a PoP (Proof Of Posession) for a secret key + +## PublicKey + +* `byte[] Serialize();` + * serialize PublicKey +* `void Deserialize(byte[] buf);` + * deserialize from byte[] buf +* `bool IsEqual(in PublicKey rhs);` + * equality +* `void Add(in PublicKey rhs);` + * add a public key rhs +* `string GetDecStr();` + * get a decimal string +* `string GetHexStr();` + * get a hexadecimal string +* `bool Verify(in Signature sig, string m);` + * verify the validness of the sig with m +* `bool VerifyPop(in Signature pop);` + * verify the validness of PoP + +## Signature + +* `byte[] Serialize();` + * serialize Signature +* `void Deserialize(byte[] buf);` + * deserialize from byte[] buf +* `bool IsEqual(in Signature rhs);` + * equality +* `void Add(in Signature rhs);` + * add a signature key rhs +* `string GetDecStr();` + * get a decimal string +* `string GetHexStr();` + * get a hexadecimal string + +## How to use + +### A minimum sample + +``` +using static BLS; + +Init(BN254); // init library +SecretKey sec; +sec.SetByCSPRNG(); // init secret key +PublicKey pub = sec.GetPublicKey(); // get public key +string m = "abc"; +Signature sig = sec.Sign(m); // create signature +if (pub.Verify(sig, m))) { + // signature is verified +} +``` + +### Aggregate signature +``` +Init(BN254); // init library +const int n = 10; +const string m = "abc"; +SecretKey[] secVec = new SecretKey[n]; +PublicKey[] pubVec = new PublicKey[n]; +Signature[] popVec = new Signature[n]; +Signature[] sigVec = new Signature[n]; + +for (int i = 0; i < n; i++) { + secVec[i].SetByCSPRNG(); // init secret key + pubVec[i] = secVec[i].GetPublicKey(); // get public key + popVec[i] = secVec[i].GetPop(); // get a proof of Possesion (PoP) + sigVec[i] = secVec[i].Sign(m); // create signature +} + +SecretKey secAgg; +PublicKey pubAgg; +Signature sigAgg; +for (int i = 0; i < n; i++) { + // verify PoP + if (pubVec[i].VerifyPop(popVec[i]))) { + // error + return; + } + pubAgg.Add(pubVec[i]); // aggregate public key + sigAgg.Add(sigVec[i]); // aggregate signature +} +if (pubAgg.Verify(sigAgg, m)) { + // aggregated signature is verified +} +``` + +# License + +modified new BSD License +http://opensource.org/licenses/BSD-3-Clause + +# Author + +(C)2019 MITSUNARI Shigeo(herumi@nifty.com) All rights reserved. diff --git a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls.go b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls.go index 5123a07e6..c83a4e658 100644 --- a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls.go +++ b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls.go @@ -1,16 +1,25 @@ package bls /* -#cgo CFLAGS:-I../../../include -I../../../../mcl/include/ -#cgo LDFLAGS:${SRCDIR}/../../../lib/libbls384.a ${SRCDIR}/../../../../mcl/lib/libmcl.a -lgmpxx -lgmp -lstdc++ -#cgo CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 -#cgo pkg-config: libcrypto -#cgo static pkg-config: --static +#cgo bn256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=4 +#cgo bn256 LDFLAGS:${SRCDIR}/../../../lib/libbls256.a +#cgo bn384 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 +#cgo bn384 LDFLAGS:${SRCDIR}/../../../lib/libbls384.a +#cgo bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 -DMCLBN_FR_UNIT_SIZE=4 +#cgo bn384_256 LDFLAGS:${SRCDIR}/../../../lib/libbls384_256.a +#cgo !bn256,!bn384,!bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 +#cgo !bn256,!bn384,!bn384_256 LDFLAGS:${SRCDIR}/../../../lib/libbls384.a +#cgo CFLAGS:-I${SRCDIR}/../../../include -I${SRCDIR}/../../../../mcl/include +#cgo LDFLAGS:${SRCDIR}/../../../../mcl/lib/libmcl.a -lgmpxx -lgmp +#cgo linux LDFLAGS:-static +typedef unsigned int (*ReadRandFunc)(void *, void *, unsigned int); +int wrapReadRandCgo(void *self, void *buf, unsigned int n); #include <bls/bls.h> */ import "C" import "fmt" import "unsafe" +import "io" import "encoding/json" // Init -- @@ -67,6 +76,9 @@ func (id *ID) SetDecString(s string) error { // IsEqual -- func (id *ID) IsEqual(rhs *ID) bool { + if id == nil || rhs == nil { + return false + } return id.v.IsEqual(&rhs.v) } @@ -146,6 +158,9 @@ func (sec *SecretKey) SetDecString(s string) error { // IsEqual -- func (sec *SecretKey) IsEqual(rhs *SecretKey) bool { + if sec == nil || rhs == nil { + return false + } return sec.v.IsEqual(&rhs.v) } @@ -264,6 +279,9 @@ func (pub *PublicKey) SetHexString(s string) error { // IsEqual -- func (pub *PublicKey) IsEqual(rhs *PublicKey) bool { + if pub == nil || rhs == nil { + return false + } return pub.v.IsEqual(&rhs.v) } @@ -350,6 +368,9 @@ func (sign *Sign) SetHexString(s string) error { // IsEqual -- func (sign *Sign) IsEqual(rhs *Sign) bool { + if sign == nil || rhs == nil { + return false + } return sign.v.IsEqual(&rhs.v) } @@ -389,6 +410,9 @@ func (sign *Sign) Verify(pub *PublicKey, m string) bool { // VerifyPop -- func (sign *Sign) VerifyPop(pub *PublicKey) bool { + if pub.getPointer() == nil { + return false + } return C.blsVerifyPop(sign.getPointer(), pub.getPointer()) == 1 } @@ -420,3 +444,96 @@ func DHKeyExchange(sec *SecretKey, pub *PublicKey) (out PublicKey) { C.blsDHKeyExchange(out.getPointer(), sec.getPointer(), pub.getPointer()) return out } + +// HashAndMapToSignature -- +func HashAndMapToSignature(buf []byte) *Sign { + sig := new(Sign) + err := sig.v.HashAndMapTo(buf) + if err == nil { + return sig + } else { + return nil + } +} + +// VerifyPairing -- +func VerifyPairing(X *Sign, Y *Sign, pub *PublicKey) bool { + if X.getPointer() == nil || Y.getPointer() == nil || pub.getPointer() == nil { + return false + } + return C.blsVerifyPairing(X.getPointer(), Y.getPointer(), pub.getPointer()) == 1 +} + +// SignHash -- +func (sec *SecretKey) SignHash(hash []byte) (sign *Sign) { + sign = new(Sign) + // #nosec + err := C.blsSignHash(sign.getPointer(), sec.getPointer(), unsafe.Pointer(&hash[0]), C.size_t(len(hash))) + if err == 0 { + return sign + } else { + return nil + } +} + +// VerifyHash -- +func (sign *Sign) VerifyHash(pub *PublicKey, hash []byte) bool { + if pub.getPointer() == nil { + return false + } + // #nosec + return C.blsVerifyHash(sign.getPointer(), pub.getPointer(), unsafe.Pointer(&hash[0]), C.size_t(len(hash))) == 1 +} + +func Min(x, y int) int { + if x < y { + return x + } + return y +} + +// VerifyAggregateHashes -- +func (sign *Sign) VerifyAggregateHashes(pubVec []PublicKey, hash [][]byte) bool { + hashByte := GetOpUnitSize() * 8 + n := len(hash) + h := make([]byte, n*hashByte) + for i := 0; i < n; i++ { + hn := len(hash[i]) + copy(h[i*hashByte:(i+1)*hashByte], hash[i][0:Min(hn, hashByte)]) + } + if pubVec[0].getPointer() == nil { + return false + } + return C.blsVerifyAggregatedHashes(sign.getPointer(), pubVec[0].getPointer(), unsafe.Pointer(&h[0]), C.size_t(hashByte), C.size_t(n)) == 1 +} + +/// + +var s_randReader io.Reader + +func createSlice(buf *C.char, n C.uint) []byte { + size := int(n) + return (*[1 << 30]byte)(unsafe.Pointer(buf))[:size:size] +} + +// this function can't be put in callback.go +//export wrapReadRandGo +func wrapReadRandGo(buf *C.char, n C.uint) C.uint { + slice := createSlice(buf, n) + ret, err := s_randReader.Read(slice) + if ret == int(n) && err == nil { + return n + } + return 0 +} + +// SetRandFunc -- +func SetRandFunc(randReader io.Reader) { + s_randReader = randReader + if randReader != nil { + C.blsSetRandFunc(nil, C.ReadRandFunc(unsafe.Pointer(C.wrapReadRandCgo))) + } else { + // use default random generator + C.blsSetRandFunc(nil, C.ReadRandFunc(unsafe.Pointer(nil))) + } +} diff --git a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls_test.go b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls_test.go new file mode 100644 index 000000000..a13ee02f4 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/bls_test.go @@ -0,0 +1,690 @@ +package bls + +import "testing" +import "strconv" +import "crypto/sha256" +import "crypto/sha512" +import "fmt" +import "crypto/rand" + +var unitN = 0 + +// Tests (for Benchmarks see below) + +func testPre(t *testing.T) { + t.Log("init") + { + var id ID + err := id.SetLittleEndian([]byte{6, 5, 4, 3, 2, 1}) + if err != nil { + t.Error(err) + } + t.Log("id :", id.GetHexString()) + var id2 ID + err = id2.SetHexString(id.GetHexString()) + if err != nil { + t.Fatal(err) + } + if !id.IsEqual(&id2) { + t.Errorf("not same id\n%s\n%s", id.GetHexString(), id2.GetHexString()) + } + err = id2.SetDecString(id.GetDecString()) + if err != nil { + t.Fatal(err) + } + if !id.IsEqual(&id2) { + t.Errorf("not same id\n%s\n%s", id.GetDecString(), id2.GetDecString()) + } + } + { + var sec SecretKey + err := sec.SetLittleEndian([]byte{1, 2, 3, 4, 5, 6}) + if err != nil { + t.Error(err) + } + t.Log("sec=", sec.GetHexString()) + } + + t.Log("create secret key") + m := "this is a bls sample for go" + var sec SecretKey + sec.SetByCSPRNG() + t.Log("sec:", sec.GetHexString()) + t.Log("create public key") + pub := sec.GetPublicKey() + t.Log("pub:", pub.GetHexString()) + sign := sec.Sign(m) + t.Log("sign:", sign.GetHexString()) + if !sign.Verify(pub, m) { + t.Error("Signature does not verify") + } + + // How to make array of SecretKey + { + sec := make([]SecretKey, 3) + for i := 0; i < len(sec); i++ { + sec[i].SetByCSPRNG() + t.Log("sec=", sec[i].GetHexString()) + } + } +} + +func testStringConversion(t *testing.T) { + t.Log("testRecoverSecretKey") + var sec SecretKey + var s string + if unitN == 6 { + s = "16798108731015832284940804142231733909759579603404752749028378864165570215949" + } else { + s = "40804142231733909759579603404752749028378864165570215949" + } + err := sec.SetDecString(s) + if err != nil { + t.Fatal(err) + } + if s != sec.GetDecString() { + t.Error("not equal") + } + s = sec.GetHexString() + var sec2 SecretKey + err = sec2.SetHexString(s) + if err != nil { + t.Fatal(err) + } + if !sec.IsEqual(&sec2) { + t.Error("not equal") + } +} + +func testRecoverSecretKey(t *testing.T) { + t.Log("testRecoverSecretKey") + k := 3000 + var sec SecretKey + sec.SetByCSPRNG() + t.Logf("sec=%s\n", sec.GetHexString()) + + // make master secret key + msk := sec.GetMasterSecretKey(k) + + n := k + secVec := make([]SecretKey, n) + idVec := make([]ID, n) + for i := 0; i < n; i++ { + err := idVec[i].SetLittleEndian([]byte{byte(i & 255), byte(i >> 8), 2, 3, 4, 5}) + if err != nil { + t.Error(err) + } + err = secVec[i].Set(msk, &idVec[i]) + if err != nil { + t.Error(err) + } + // t.Logf("idVec[%d]=%s\n", i, idVec[i].GetHexString()) + } + // recover sec2 from secVec and idVec + var sec2 SecretKey + err := sec2.Recover(secVec, idVec) + if err != nil { + t.Error(err) + } + if !sec.IsEqual(&sec2) { + t.Errorf("Mismatch in recovered secret key:\n %s\n %s.", sec.GetHexString(), sec2.GetHexString()) + } +} + +func testEachSign(t *testing.T, m string, msk []SecretKey, mpk []PublicKey) ([]ID, []SecretKey, []PublicKey, []Sign) { + idTbl := []byte{3, 5, 193, 22, 15} + n := len(idTbl) + + secVec := make([]SecretKey, n) + pubVec := make([]PublicKey, n) + signVec := make([]Sign, n) + idVec := make([]ID, n) + + for i := 0; i < n; i++ { + err := idVec[i].SetLittleEndian([]byte{idTbl[i], 0, 0, 0, 0, 0}) + if err != nil { + t.Error(err) + } + t.Logf("idVec[%d]=%s\n", i, idVec[i].GetHexString()) + + err = secVec[i].Set(msk, &idVec[i]) + if err != nil { + t.Error(err) + } + + err = pubVec[i].Set(mpk, &idVec[i]) + if err != nil { + t.Error(err) + } + t.Logf("pubVec[%d]=%s\n", i, pubVec[i].GetHexString()) + + if !pubVec[i].IsEqual(secVec[i].GetPublicKey()) { + t.Errorf("Pubkey derivation does not match\n%s\n%s", pubVec[i].GetHexString(), secVec[i].GetPublicKey().GetHexString()) + } + + signVec[i] = *secVec[i].Sign(m) + if !signVec[i].Verify(&pubVec[i], m) { + t.Error("Pubkey derivation does not match") + } + } + return idVec, secVec, pubVec, signVec +} +func testSign(t *testing.T) { + m := "testSign" + t.Log(m) + + var sec0 SecretKey + sec0.SetByCSPRNG() + pub0 := sec0.GetPublicKey() + s0 := sec0.Sign(m) + if !s0.Verify(pub0, m) { + t.Error("Signature does not verify") + } + + k := 3 + msk := sec0.GetMasterSecretKey(k) + mpk := GetMasterPublicKey(msk) + idVec, secVec, pubVec, signVec := testEachSign(t, m, msk, mpk) + + var sec1 SecretKey + err := sec1.Recover(secVec, idVec) + if err != nil { + t.Error(err) + } + if !sec0.IsEqual(&sec1) { + t.Error("Mismatch in recovered seckey.") + } + var pub1 PublicKey + err = pub1.Recover(pubVec, idVec) + if err != nil { + t.Error(err) + } + if !pub0.IsEqual(&pub1) { + t.Error("Mismatch in recovered pubkey.") + } + var s1 Sign + err = s1.Recover(signVec, idVec) + if err != nil { + t.Error(err) + } + if !s0.IsEqual(&s1) { + t.Error("Mismatch in recovered signature.") + } +} + +func testAdd(t *testing.T) { + t.Log("testAdd") + var sec1 SecretKey + var sec2 SecretKey + sec1.SetByCSPRNG() + sec2.SetByCSPRNG() + + pub1 := sec1.GetPublicKey() + pub2 := sec2.GetPublicKey() + + m := "test test" + sign1 := sec1.Sign(m) + sign2 := sec2.Sign(m) + + t.Log("sign1 :", sign1.GetHexString()) + sign1.Add(sign2) + t.Log("sign1 add:", sign1.GetHexString()) + pub1.Add(pub2) + if !sign1.Verify(pub1, m) { + t.Fail() + } +} + +func testPop(t *testing.T) { + t.Log("testPop") + var sec SecretKey + sec.SetByCSPRNG() + pop := sec.GetPop() + if !pop.VerifyPop(sec.GetPublicKey()) { + t.Errorf("Valid Pop does not verify") + } + sec.SetByCSPRNG() + if pop.VerifyPop(sec.GetPublicKey()) { + t.Errorf("Invalid Pop verifies") + } +} + +func testData(t *testing.T) { + t.Log("testData") + var sec1, sec2 SecretKey + sec1.SetByCSPRNG() + b := sec1.GetLittleEndian() + err := sec2.SetLittleEndian(b) + if err != nil { + t.Fatal(err) + } + if !sec1.IsEqual(&sec2) { + t.Error("SecretKey not same") + } + pub1 := sec1.GetPublicKey() + b = pub1.Serialize() + var pub2 PublicKey + err = pub2.Deserialize(b) + if err != nil { + t.Fatal(err) + } + if !pub1.IsEqual(&pub2) { + t.Error("PublicKey not same") + } + m := "doremi" + sign1 := sec1.Sign(m) + b = sign1.Serialize() + var sign2 Sign + err = sign2.Deserialize(b) + if err != nil { + t.Fatal(err) + } + if !sign1.IsEqual(&sign2) { + t.Error("Sign not same") + } +} + +func testSerializeToHexStr(t *testing.T) { + t.Log("testSerializeToHexStr") + var sec1, sec2 SecretKey + sec1.SetByCSPRNG() + s := sec1.SerializeToHexStr() + err := sec2.DeserializeHexStr(s) + if err != nil { + t.Fatal(err) + } + if !sec1.IsEqual(&sec2) { + t.Error("SecretKey not same") + } + pub1 := sec1.GetPublicKey() + s = pub1.SerializeToHexStr() + var pub2 PublicKey + err = pub2.DeserializeHexStr(s) + if err != nil { + t.Fatal(err) + } + if !pub1.IsEqual(&pub2) { + t.Error("PublicKey not same") + } + m := "doremi" + sign1 := sec1.Sign(m) + s = sign1.SerializeToHexStr() + var sign2 Sign + err = sign2.DeserializeHexStr(s) + if err != nil { + t.Fatal(err) + } + if !sign1.IsEqual(&sign2) { + t.Error("Sign not same") + } +} + +func testOrder(t *testing.T, c int) { + var curve string + var field string + if c == CurveFp254BNb { + curve = "16798108731015832284940804142231733909759579603404752749028378864165570215949" + field = "16798108731015832284940804142231733909889187121439069848933715426072753864723" + } else if c == CurveFp382_1 { + curve = "5540996953667913971058039301942914304734176495422447785042938606876043190415948413757785063597439175372845535461389" + field = "5540996953667913971058039301942914304734176495422447785045292539108217242186829586959562222833658991069414454984723" + } else if c == CurveFp382_2 { + curve = "5541245505022739011583672869577435255026888277144126952448297309161979278754528049907713682488818304329661351460877" + field = "5541245505022739011583672869577435255026888277144126952450651294188487038640194767986566260919128250811286032482323" + } else if c == BLS12_381 { + curve = "52435875175126190479447740508185965837690552500527637822603658699938581184513" + field = "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787" + } else { + t.Fatal("bad c", c) + } + s := GetCurveOrder() + if s != curve { + t.Errorf("bad curve order\n%s\n%s\n", s, curve) + } + s = GetFieldOrder() + if s != field { + t.Errorf("bad field order\n%s\n%s\n", s, field) + } +} + +func testDHKeyExchange(t *testing.T) { + var sec1, sec2 SecretKey + sec1.SetByCSPRNG() + sec2.SetByCSPRNG() + pub1 := sec1.GetPublicKey() + pub2 := sec2.GetPublicKey() + out1 := DHKeyExchange(&sec1, pub2) + out2 := DHKeyExchange(&sec2, pub1) + if !out1.IsEqual(&out2) { + t.Errorf("DH key is not equal") + } +} + +func testPairing(t *testing.T) { + var sec SecretKey + sec.SetByCSPRNG() + pub := sec.GetPublicKey() + m := "abc" + sig1 := sec.Sign(m) + sig2 := HashAndMapToSignature([]byte(m)) + if !VerifyPairing(sig1, sig2, pub) { + t.Errorf("VerifyPairing") + } +} + +func testAggregate(t *testing.T) { + var sec SecretKey + sec.SetByCSPRNG() + pub := sec.GetPublicKey() + msgTbl := []string{"abc", "def", "123"} + n := len(msgTbl) + sigVec := make([]*Sign, n) + for i := 0; i < n; i++ { + m := msgTbl[i] + sigVec[i] = sec.Sign(m) + } + aggSign := sigVec[0] + for i := 1; i < n; i++ { + aggSign.Add(sigVec[i]) + } + hashPt := HashAndMapToSignature([]byte(msgTbl[0])) + for i := 1; i < n; i++ { + hashPt.Add(HashAndMapToSignature([]byte(msgTbl[i]))) + } + if !VerifyPairing(aggSign, hashPt, pub) { + t.Errorf("aggregate2") + } +} + +func Hash(buf []byte) []byte { + if GetOpUnitSize() == 4 { + d := sha256.Sum256([]byte(buf)) + return d[:] + } else { + // use SHA512 if bitSize > 256 + d := sha512.Sum512([]byte(buf)) + return d[:] + } +} + +func testHash(t *testing.T) { + var sec SecretKey + sec.SetByCSPRNG() + pub := sec.GetPublicKey() + m := "abc" + h := Hash([]byte(m)) + sig1 := sec.Sign(m) + sig2 := sec.SignHash(h) + if !sig1.IsEqual(sig2) { + t.Errorf("SignHash") + } + if !sig1.Verify(pub, m) { + t.Errorf("sig1.Verify") + } + if !sig2.VerifyHash(pub, h) { + t.Errorf("sig2.VerifyHash") + } +} + +func testAggregateHashes(t *testing.T) { + n := 1000 + pubVec := make([]PublicKey, n) + sigVec := make([]*Sign, n) + h := make([][]byte, n) + for i := 0; i < n; i++ { + sec := new(SecretKey) + sec.SetByCSPRNG() + pubVec[i] = *sec.GetPublicKey() + m := fmt.Sprintf("abc-%d", i) + h[i] = Hash([]byte(m)) + sigVec[i] = sec.SignHash(h[i]) + } + // aggregate sig + sig := sigVec[0] + for i := 1; i < n; i++ { + sig.Add(sigVec[i]) + } + if !sig.VerifyAggregateHashes(pubVec, h) { + t.Errorf("sig.VerifyAggregateHashes") + } +} + +type SeqRead struct { +} + +func (self *SeqRead) Read(buf []byte) (int, error) { + n := len(buf) + for i := 0; i < n; i++ { + buf[i] = byte(i) + } + return n, nil +} + +func testReadRand(t *testing.T) { + s1 := new(SeqRead) + SetRandFunc(s1) + var sec SecretKey + sec.SetByCSPRNG() + buf := sec.GetLittleEndian() + fmt.Printf("(SeqRead) buf=%x\n", buf) + for i := 0; i < len(buf)-1; i++ { + // ommit buf[len(buf) - 1] because it may be masked + if buf[i] != byte(i) { + t.Fatal("buf") + } + } + SetRandFunc(rand.Reader) + sec.SetByCSPRNG() + buf = sec.GetLittleEndian() + fmt.Printf("(rand.Reader) buf=%x\n", buf) + SetRandFunc(nil) + sec.SetByCSPRNG() + buf = sec.GetLittleEndian() + fmt.Printf("(default) buf=%x\n", buf) +} + +func test(t *testing.T, c int) { + err := Init(c) + if err != nil { + t.Fatal(err) + } + unitN = GetOpUnitSize() + t.Logf("unitN=%d\n", unitN) + testReadRand(t) + testPre(t) + testRecoverSecretKey(t) + testAdd(t) + testSign(t) + testPop(t) + testData(t) + testStringConversion(t) + testOrder(t, c) + testDHKeyExchange(t) + testSerializeToHexStr(t) + testPairing(t) + testAggregate(t) + testHash(t) + testAggregateHashes(t) +} + +func TestMain(t *testing.T) { + t.Logf("GetMaxOpUnitSize() = %d\n", GetMaxOpUnitSize()) + t.Log("CurveFp254BNb") + test(t, CurveFp254BNb) + if GetMaxOpUnitSize() == 6 { + if GetFrUnitSize() == 6 { + t.Log("CurveFp382_1") + test(t, CurveFp382_1) + } + t.Log("BLS12_381") + test(t, BLS12_381) + } +} + +// Benchmarks + +var curve = CurveFp382_1 + +//var curve = CurveFp254BNb + +func BenchmarkPubkeyFromSeckey(b *testing.B) { + b.StopTimer() + err := Init(curve) + if err != nil { + b.Fatal(err) + } + var sec SecretKey + for n := 0; n < b.N; n++ { + sec.SetByCSPRNG() + b.StartTimer() + sec.GetPublicKey() + b.StopTimer() + } +} + +func BenchmarkSigning(b *testing.B) { + b.StopTimer() + err := Init(curve) + if err != nil { + b.Fatal(err) + } + var sec SecretKey + for n := 0; n < b.N; n++ { + sec.SetByCSPRNG() + b.StartTimer() + sec.Sign(strconv.Itoa(n)) + b.StopTimer() + } +} + +func BenchmarkValidation(b *testing.B) { + b.StopTimer() + err := Init(curve) + if err != nil { + b.Fatal(err) + } + var sec SecretKey + for n := 0; n < b.N; n++ { + sec.SetByCSPRNG() + pub := sec.GetPublicKey() + m := strconv.Itoa(n) + sig := sec.Sign(m) + b.StartTimer() + sig.Verify(pub, m) + b.StopTimer() + } +} + +func benchmarkDeriveSeckeyShare(k int, b *testing.B) { + b.StopTimer() + err := Init(curve) + if err != nil { + b.Fatal(err) + } + var sec SecretKey + sec.SetByCSPRNG() + msk := sec.GetMasterSecretKey(k) + var id ID + for n := 0; n < b.N; n++ { + err = id.SetLittleEndian([]byte{1, 2, 3, 4, 5, byte(n)}) + if err != nil { + b.Error(err) + } + b.StartTimer() + err := sec.Set(msk, &id) + b.StopTimer() + if err != nil { + b.Error(err) + } + } +} + +//func BenchmarkDeriveSeckeyShare100(b *testing.B) { benchmarkDeriveSeckeyShare(100, b) } +//func BenchmarkDeriveSeckeyShare200(b *testing.B) { benchmarkDeriveSeckeyShare(200, b) } +func BenchmarkDeriveSeckeyShare500(b *testing.B) { benchmarkDeriveSeckeyShare(500, b) } + +//func BenchmarkDeriveSeckeyShare1000(b *testing.B) { benchmarkDeriveSeckeyShare(1000, b) } + +func benchmarkRecoverSeckey(k int, b *testing.B) { + b.StopTimer() + err := Init(curve) + if err != nil { + b.Fatal(err) + } + var sec SecretKey + sec.SetByCSPRNG() + msk := sec.GetMasterSecretKey(k) + + // derive n shares + n := k + secVec := make([]SecretKey, n) + idVec := make([]ID, n) + for i := 0; i < n; i++ { + err := idVec[i].SetLittleEndian([]byte{1, 2, 3, 4, 5, byte(i)}) + if err != nil { + b.Error(err) + } + err = secVec[i].Set(msk, &idVec[i]) + if err != nil { + b.Error(err) + } + } + + // recover from secVec and idVec + var sec2 SecretKey + b.StartTimer() + for n := 0; n < b.N; n++ { + err := sec2.Recover(secVec, idVec) + if err != nil { + b.Errorf("%s\n", err) + } + } +} + +func BenchmarkRecoverSeckey100(b *testing.B) { benchmarkRecoverSeckey(100, b) } +func BenchmarkRecoverSeckey200(b *testing.B) { benchmarkRecoverSeckey(200, b) } +func BenchmarkRecoverSeckey500(b *testing.B) { benchmarkRecoverSeckey(500, b) } +func BenchmarkRecoverSeckey1000(b *testing.B) { benchmarkRecoverSeckey(1000, b) } + +func benchmarkRecoverSignature(k int, b *testing.B) { + b.StopTimer() + err := Init(curve) + if err != nil { + b.Fatal(err) + } + var sec SecretKey + sec.SetByCSPRNG() + msk := sec.GetMasterSecretKey(k) + + // derive n shares + n := k + idVec := make([]ID, n) + secVec := make([]SecretKey, n) + signVec := make([]Sign, n) + for i := 0; i < n; i++ { + err := idVec[i].SetLittleEndian([]byte{1, 2, 3, 4, 5, byte(i)}) + if err != nil { + b.Error(err) + } + err = secVec[i].Set(msk, &idVec[i]) + if err != nil { + b.Error(err) + } + signVec[i] = *secVec[i].Sign("test message") + } + + // recover signature + var sig Sign + b.StartTimer() + for n := 0; n < b.N; n++ { + err := sig.Recover(signVec, idVec) + if err != nil { + b.Error(err) + } + } +} + +func BenchmarkRecoverSignature100(b *testing.B) { benchmarkRecoverSignature(100, b) } +func BenchmarkRecoverSignature200(b *testing.B) { benchmarkRecoverSignature(200, b) } +func BenchmarkRecoverSignature500(b *testing.B) { benchmarkRecoverSignature(500, b) } +func BenchmarkRecoverSignature1000(b *testing.B) { benchmarkRecoverSignature(1000, b) } diff --git a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/callback.go b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/callback.go new file mode 100644 index 000000000..ba73a5e15 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/callback.go @@ -0,0 +1,12 @@ +package bls + +/* +// exported from bls.go +unsigned int wrapReadRandGo(void *buf, unsigned int n); +int wrapReadRandCgo(void *self, void *buf, unsigned int n) +{ + (void)self; + return wrapReadRandGo(buf, n); +} +*/ +import "C" diff --git a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/config.h b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/config.h new file mode 100644 index 000000000..07e148137 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/config.h @@ -0,0 +1,6 @@ +#pragma +// use bn384 unless tags is specified +#ifndef MCLBN_FP_UNIT_SIZE + #define MCLBN_FP_UNIT_SIZE 6 +#endif + diff --git a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/dummy.cpp b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/dummy.cpp new file mode 100644 index 000000000..a5103a1c5 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/dummy.cpp @@ -0,0 +1,3 @@ +// This is a dummy source file which forces cgo to use the C++ linker instead +// of the default C linker. We can therefore eliminate non-portable linker +// flags such as -lstdc++, which is likely to break on FreeBSD and OpenBSD. diff --git a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/mcl.go b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/mcl.go index 9771201ec..ca8d7f02b 100644 --- a/vendor/github.com/dexon-foundation/bls/ffi/go/bls/mcl.go +++ b/vendor/github.com/dexon-foundation/bls/ffi/go/bls/mcl.go @@ -1,7 +1,10 @@ package bls /* -#cgo CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 +#cgo bn256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=4 +#cgo bn384 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 +#cgo bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 -DMCLBN_FR_UNIT_SIZE=4 +#cgo !bn256,!bn384,!bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 #include <mcl/bn.h> */ import "C" @@ -23,6 +26,17 @@ const BLS12_381 = C.MCL_BLS12_381 // IoSerializeHexStr const IoSerializeHexStr = C.MCLBN_IO_SERIALIZE_HEX_STR +// GetFrUnitSize() -- +func GetFrUnitSize() int { + return int(C.MCLBN_FR_UNIT_SIZE) +} + +// GetFpUnitSize() -- +// same as GetMaxOpUnitSize() +func GetFpUnitSize() int { + return int(C.MCLBN_FP_UNIT_SIZE) +} + // GetMaxOpUnitSize -- func GetMaxOpUnitSize() int { return int(C.MCLBN_FP_UNIT_SIZE) diff --git a/vendor/github.com/dexon-foundation/bls/images/bls-go-alpine/Dockerfile b/vendor/github.com/dexon-foundation/bls/images/bls-go-alpine/Dockerfile new file mode 100644 index 000000000..edd49eb4b --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/images/bls-go-alpine/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:alpine +MAINTAINER Jimmy Hu <jimmy.hu@dexon.org> + +# Install dependencies +RUN apk add --update-cache build-base gmp-dev openssl-dev git + +# Build bls library +RUN mkdir work ; cd work +RUN git clone --depth 1 git://github.com/dexon-foundation/mcl.git +RUN mkdir bls +COPY . bls/ +RUN cd bls ; make clean && make test_go DOCKER=alpine -j && cp lib/* /usr/lib/ diff --git a/vendor/github.com/dexon-foundation/bls/include/bls/bls.h b/vendor/github.com/dexon-foundation/bls/include/bls/bls.h index 6b7cbdd68..cb300bc49 100644 --- a/vendor/github.com/dexon-foundation/bls/include/bls/bls.h +++ b/vendor/github.com/dexon-foundation/bls/include/bls/bls.h @@ -8,6 +8,14 @@ */ #include <mcl/bn.h> +#ifdef BLS_SWAP_G + /* + error if BLS_SWAP_G is inconsistently used between library and exe + */ + #undef MCLBN_COMPILED_TIME_VAR + #define MCLBN_COMPILED_TIME_VAR ((MCLBN_FR_UNIT_SIZE) * 10 + (MCLBN_FP_UNIT_SIZE) + 100) +#endif + #ifdef _MSC_VER #ifdef BLS_DONT_EXPORT #define BLS_DLL_API @@ -21,7 +29,9 @@ #ifndef BLS_NO_AUTOLINK #if MCLBN_FP_UNIT_SIZE == 4 #pragma comment(lib, "bls256.lib") - #elif MCLBN_FP_UNIT_SIZE == 6 + #elif (MCLBN_FP_UNIT_SIZE == 6) && (MCLBN_FR_UNIT_SIZE == 4) + #pragma comment(lib, "bls384_256.lib") + #elif (MCLBN_FP_UNIT_SIZE == 6) && (MCLBN_FR_UNIT_SIZE == 6) #pragma comment(lib, "bls384.lib") #endif #endif @@ -46,11 +56,19 @@ typedef struct { } blsSecretKey; typedef struct { +#ifdef BLS_SWAP_G + mclBnG1 v; +#else mclBnG2 v; +#endif } blsPublicKey; typedef struct { +#ifdef BLS_SWAP_G + mclBnG2 v; +#else mclBnG1 v; +#endif } blsSignature; /* @@ -68,9 +86,13 @@ BLS_DLL_API int blsInit(int curve, int compiledTimeVar); BLS_DLL_API void blsIdSetInt(blsId *id, int x); -// return 0 if success -// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r +// sec = buf & (1 << bitLen(r)) - 1 +// if (sec >= r) sec &= (1 << (bitLen(r) - 1)) - 1 +// always return 0 BLS_DLL_API int blsSecretKeySetLittleEndian(blsSecretKey *sec, const void *buf, mclSize bufSize); +// return 0 if success (bufSize <= 64) else -1 +// set (buf mod r) to sec +BLS_DLL_API int blsSecretKeySetLittleEndianMod(blsSecretKey *sec, const void *buf, mclSize bufSize); BLS_DLL_API void blsGetPublicKey(blsPublicKey *pub, const blsSecretKey *sec); @@ -126,6 +148,15 @@ BLS_DLL_API int blsPublicKeyIsValidOrder(const blsPublicKey *pub); #ifndef BLS_MINIMUM_API /* + verify X == sY by checking e(X, sQ) = e(Y, Q) + @param X [in] + @param Y [in] + @param pub [in] pub = sQ + @return 1 if e(X, pub) = e(Y, Q) else 0 +*/ +BLS_DLL_API int blsVerifyPairing(const blsSignature *X, const blsSignature *Y, const blsPublicKey *pub); + +/* sign the hash use the low (bitSize of r) - 1 bit of h return 0 if success else -1 @@ -162,8 +193,13 @@ BLS_DLL_API int blsGetG1ByteSize(void); // return bytes for serialized Fr BLS_DLL_API int blsGetFrByteSize(void); +#ifdef BLS_SWAP_G +// get a generator of G1 +BLS_DLL_API void blsGetGeneratorOfG1(blsPublicKey *pub); +#else // get a generator of G2 BLS_DLL_API void blsGetGeneratorOfG2(blsPublicKey *pub); +#endif // return 0 if success BLS_DLL_API int blsIdSetDecStr(blsId *id, const char *buf, mclSize bufSize); @@ -184,6 +220,15 @@ BLS_DLL_API int blsHashToSecretKey(blsSecretKey *sec, const void *buf, mclSize b return 0 if success else -1 */ BLS_DLL_API int blsSecretKeySetByCSPRNG(blsSecretKey *sec); +/* + set user-defined random function for setByCSPRNG + @param self [in] user-defined pointer + @param readFunc [in] user-defined function, + which writes random bufSize bytes to buf and returns bufSize if success else returns 0 + @note if self == 0 and readFunc == 0 then set default random function + @note not threadsafe +*/ +BLS_DLL_API void blsSetRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)); #endif BLS_DLL_API void blsGetPop(blsSignature *sig, const blsSecretKey *sec); diff --git a/vendor/github.com/dexon-foundation/bls/include/bls/bls.hpp b/vendor/github.com/dexon-foundation/bls/include/bls/bls.hpp index b32b7e1fa..741334555 100644 --- a/vendor/github.com/dexon-foundation/bls/include/bls/bls.hpp +++ b/vendor/github.com/dexon-foundation/bls/include/bls/bls.hpp @@ -250,7 +250,7 @@ public: */ void recover(const SecretKeyVec& secVec, const IdVec& idVec) { - if (secVec.size() != idVec.size()) throw std::invalid_argument("SecretKey::recover"); + if (secVec.size() != idVec.size()) throw std::invalid_argument("SecretKey:recover"); recover(secVec.data(), idVec.data(), idVec.size()); } /* @@ -300,7 +300,12 @@ public: if (str != "0") { // 1 <x.a> <x.b> <y.a> <y.b> std::string t; - for (int i = 0; i < 4; i++) { +#ifdef BLS_SWAP_G + const int elemNum = 2; +#else + const int elemNum = 4; +#endif + for (int i = 0; i < elemNum; i++) { is >> t; str += ' '; str += t; @@ -312,14 +317,22 @@ public: void getStr(std::string& str, int ioMode = 0) const { str.resize(1024); +#ifdef BLS_SWAP_G + size_t n = mclBnG1_getStr(&str[0], str.size(), &self_.v, ioMode); +#else size_t n = mclBnG2_getStr(&str[0], str.size(), &self_.v, ioMode); - if (n == 0) throw std::runtime_error("mclBnG2_getStr"); +#endif + if (n == 0) throw std::runtime_error("PublicKey:getStr"); str.resize(n); } void setStr(const std::string& str, int ioMode = 0) { +#ifdef BLS_SWAP_G + int ret = mclBnG1_setStr(&self_.v, str.c_str(), str.size(), ioMode); +#else int ret = mclBnG2_setStr(&self_.v, str.c_str(), str.size(), ioMode); - if (ret != 0) throw std::runtime_error("mclBnG2_setStr"); +#endif + if (ret != 0) throw std::runtime_error("PublicKey:setStr"); } /* set public for id from mpk @@ -333,7 +346,7 @@ public: */ void recover(const PublicKeyVec& pubVec, const IdVec& idVec) { - if (pubVec.size() != idVec.size()) throw std::invalid_argument("PublicKey::recover"); + if (pubVec.size() != idVec.size()) throw std::invalid_argument("PublicKey:recover"); recover(pubVec.data(), idVec.data(), idVec.size()); } /* @@ -382,7 +395,12 @@ public: if (str != "0") { // 1 <x> <y> std::string t; - for (int i = 0; i < 2; i++) { +#ifdef BLS_SWAP_G + const int elemNum = 4; +#else + const int elemNum = 2; +#endif + for (int i = 0; i < elemNum; i++) { is >> t; str += ' '; str += t; @@ -394,14 +412,22 @@ public: void getStr(std::string& str, int ioMode = 0) const { str.resize(1024); +#ifdef BLS_SWAP_G + size_t n = mclBnG2_getStr(&str[0], str.size(), &self_.v, ioMode); +#else size_t n = mclBnG1_getStr(&str[0], str.size(), &self_.v, ioMode); - if (n == 0) throw std::runtime_error("mclBnG1_getStr"); +#endif + if (n == 0) throw std::runtime_error("Signature:tgetStr"); str.resize(n); } void setStr(const std::string& str, int ioMode = 0) { +#ifdef BLS_SWAP_G + int ret = mclBnG2_setStr(&self_.v, str.c_str(), str.size(), ioMode); +#else int ret = mclBnG1_setStr(&self_.v, str.c_str(), str.size(), ioMode); - if (ret != 0) throw std::runtime_error("mclBnG1_setStr"); +#endif + if (ret != 0) throw std::runtime_error("Signature:setStr"); } bool verify(const PublicKey& pub, const void *m, size_t size) const { @@ -437,7 +463,7 @@ public: */ void recover(const SignatureVec& sigVec, const IdVec& idVec) { - if (sigVec.size() != idVec.size()) throw std::invalid_argument("Signature::recover"); + if (sigVec.size() != idVec.size()) throw std::invalid_argument("Signature:recover"); recover(sigVec.data(), idVec.data(), idVec.size()); } /* diff --git a/vendor/github.com/dexon-foundation/bls/mk.bat b/vendor/github.com/dexon-foundation/bls/mk.bat index c5dfac91a..9bf8dd9e6 100644 --- a/vendor/github.com/dexon-foundation/bls/mk.bat +++ b/vendor/github.com/dexon-foundation/bls/mk.bat @@ -8,6 +8,7 @@ if "%1"=="-s" ( echo "mk (-s|-d) <source file>" goto exit ) +set CFLAGS=%CFLAGS% -I../mcl/include set SRC=%2 set EXE=%SRC:.cpp=.exe% set EXE=%EXE:.c=.exe% diff --git a/vendor/github.com/dexon-foundation/bls/mklib.bat b/vendor/github.com/dexon-foundation/bls/mklib.bat index fca9333fc..4a60d7196 100644 --- a/vendor/github.com/dexon-foundation/bls/mklib.bat +++ b/vendor/github.com/dexon-foundation/bls/mklib.bat @@ -10,13 +10,17 @@ call setvar.bat if "%1"=="dll" ( cl /c %CFLAGS% /Foobj/bls_c256.obj src/bls_c256.cpp /DBLS_NO_AUTOLINK cl /c %CFLAGS% /Foobj/bls_c384.obj src/bls_c384.cpp /DBLS_NO_AUTOLINK + cl /c %CFLAGS% /Foobj/bls_c384_256.obj src/bls_c384_256.cpp /DBLS_NO_AUTOLINK cl /c %CFLAGS% /Foobj/fp.obj ../mcl/src/fp.cpp link /nologo /DLL /OUT:bin\bls256.dll obj\bls_c256.obj obj\fp.obj %LDFLAGS% /implib:lib\bls256.lib link /nologo /DLL /OUT:bin\bls384.dll obj\bls_c384.obj obj\fp.obj %LDFLAGS% /implib:lib\bls384.lib + link /nologo /DLL /OUT:bin\bls384_256.dll obj\bls_c384_256.obj obj\fp.obj %LDFLAGS% /implib:lib\bls384_256.lib ) else ( cl /c %CFLAGS% /Foobj/bls_c256.obj src/bls_c256.cpp cl /c %CFLAGS% /Foobj/bls_c384.obj src/bls_c384.cpp + cl /c %CFLAGS% /Foobj/bls_c384_256.obj src/bls_c384_256.cpp cl /c %CFLAGS% /Foobj/fp.obj ../mcl/src/fp.cpp /DMCLBN_DONT_EXPORT lib /OUT:lib/bls256.lib /nodefaultlib obj/bls_c256.obj obj/fp.obj %LDFLAGS% lib /OUT:lib/bls384.lib /nodefaultlib obj/bls_c384.obj obj/fp.obj %LDFLAGS% + lib /OUT:lib/bls384_256.lib /nodefaultlib obj/bls_c384_256.obj obj/fp.obj %LDFLAGS% ) diff --git a/vendor/github.com/dexon-foundation/bls/readme.md b/vendor/github.com/dexon-foundation/bls/readme.md index 08aac6ca1..b1efb3f36 100644 --- a/vendor/github.com/dexon-foundation/bls/readme.md +++ b/vendor/github.com/dexon-foundation/bls/readme.md @@ -15,7 +15,23 @@ git clone git://github.com/dexon-foundation/bls.git git clone git://github.com/herumi/cybozulib_ext ; for only Windows ``` -# **REMARK** libbls.a for C++ interface(bls/bls.hpp) is removed +# News +* (Break backward compatibility) The suffix `_dy` of library name is removed and bls\*.a requires libmcl.so set LD_LIBRARY_PATH to the directory. +* -tags option for Go bindings + * -tags bn256 + * -tags bn384\_256 + * -tags bn384 ; default mode +* Support swap of G1 and G2 + * `make BLS_SWAP_G=1` then G1 is assigned to PublicKey and G2 is assigned to Signature. + * golang binding does not support this feature yet. +* Build option without GMP + * `make MCL_USE_GMP=0` +* Build option without OpenSSL + * `make MCL_USE_OPENSSL=0` +* Build option to specify `mcl` directory + * `make MCL_DIR=<mcl directory>` + +* (old) libbls.a for C++ interface(bls/bls.hpp) is removed Link `lib/libbls256.a` or `lib/libbls384.a` to use `bls/bls.hpp` according to MCLBN_FP_UNIT_SIZE = 4 or 6. # Build and test for Linux @@ -45,8 +61,9 @@ bin\bls_c384_test.exe ``` # Library -* libbls256.a/libbls256_dy.so ; for BN254 compiled with MCLBN_FP_UNIT_SIZE=4 -* libbls384.a/libbls384_dy.so ; for BN254/BN381_1/BLS12_381 compiled with MCLBN_FP_UNIT_SIZE=6 +* libbls256.a/libbls256.so ; for BN254 compiled with MCLBN_FP_UNIT_SIZE=4 +* libbls384.a/libbls384.so ; for BN254/BN381_1/BLS12_381 compiled with MCLBN_FP_UNIT_SIZE=6 +* libbls384_256.a/libbls384_256.so ; for BN254/BLS12_381 compiled with MCLBN_FP_UNIT_SIZE=6 and MCLBN_FR_UNIT_SIZE=4 See `mcl/include/curve_type.h` for curve parameter diff --git a/vendor/github.com/dexon-foundation/bls/sample/bls_smpl.cpp b/vendor/github.com/dexon-foundation/bls/sample/bls_smpl.cpp new file mode 100644 index 000000000..e812cd500 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/sample/bls_smpl.cpp @@ -0,0 +1,168 @@ +#define MCLBN_FP_UNIT_SIZE 4 +#include <bls/bls.hpp> +#include <cybozu/option.hpp> +#include <cybozu/itoa.hpp> +#include <fstream> + +const std::string pubFile = "sample/publickey"; +const std::string secFile = "sample/secretkey"; +const std::string signFile = "sample/sign"; + +std::string makeName(const std::string& name, const bls::Id& id) +{ + const std::string suf = ".txt"; + if (id.isZero()) return name + suf; + std::ostringstream os; + os << name << '.' << id << suf; + return os.str(); +} + +template<class T> +void save(const std::string& file, const T& t, const bls::Id& id = 0) +{ + const std::string name = makeName(file, id); + std::ofstream ofs(name.c_str(), std::ios::binary); + if (!(ofs << t)) { + throw cybozu::Exception("can't save") << name; + } +} + +template<class T> +void load(T& t, const std::string& file, const bls::Id& id = 0) +{ + const std::string name = makeName(file, id); + std::ifstream ifs(name.c_str(), std::ios::binary); + if (!(ifs >> t)) { + throw cybozu::Exception("can't load") << name; + } +} + +int init() +{ + printf("make %s and %s files\n", secFile.c_str(), pubFile.c_str()); + bls::SecretKey sec; + sec.init(); + save(secFile, sec); + bls::PublicKey pub; + sec.getPublicKey(pub); + save(pubFile, pub); + return 0; +} + +int sign(const std::string& m, int id) +{ + printf("sign message `%s` by id=%d\n", m.c_str(), id); + bls::SecretKey sec; + load(sec, secFile, id); + bls::Signature s; + sec.sign(s, m); + save(signFile, s, id); + return 0; +} + +int verify(const std::string& m, int id) +{ + printf("verify message `%s` by id=%d\n", m.c_str(), id); + bls::PublicKey pub; + load(pub, pubFile, id); + bls::Signature s; + load(s, signFile, id); + if (s.verify(pub, m)) { + puts("verify ok"); + return 0; + } else { + puts("verify err"); + return 1; + } +} + +int share(size_t n, size_t k) +{ + printf("%d-out-of-%d threshold sharing\n", (int)k, (int)n); + bls::SecretKey sec; + load(sec, secFile); + bls::SecretKeyVec msk; + sec.getMasterSecretKey(msk, k); + bls::SecretKeyVec secVec(n); + bls::IdVec ids(n); + for (size_t i = 0; i < n; i++) { + int id = i + 1; + ids[i] = id; + secVec[i].set(msk, id); + } + for (size_t i = 0; i < n; i++) { + save(secFile, secVec[i], ids[i]); + bls::PublicKey pub; + secVec[i].getPublicKey(pub); + save(pubFile, pub, ids[i]); + } + return 0; +} + +int recover(const bls::IdVec& ids) +{ + printf("recover from"); + for (size_t i = 0; i < ids.size(); i++) { + std::cout << ' ' << ids[i]; + } + printf("\n"); + bls::SignatureVec sigVec(ids.size()); + for (size_t i = 0; i < sigVec.size(); i++) { + load(sigVec[i], signFile, ids[i]); + } + bls::Signature s; + s.recover(sigVec, ids); + save(signFile, s); + return 0; +} + +int main(int argc, char *argv[]) + try +{ + bls::init(); // use BN254 + + std::string mode; + std::string m; + size_t n; + size_t k; + int id; + bls::IdVec ids; + + cybozu::Option opt; + opt.appendParam(&mode, "init|sign|verify|share|recover"); + opt.appendOpt(&n, 10, "n", ": k-out-of-n threshold"); + opt.appendOpt(&k, 3, "k", ": k-out-of-n threshold"); + opt.appendOpt(&m, "", "m", ": message to be signed"); + opt.appendOpt(&id, 0, "id", ": id of secretKey"); + opt.appendVec(&ids, "ids", ": select k id in [0, n). this option should be last"); + opt.appendHelp("h"); + if (!opt.parse(argc, argv)) { + goto ERR_EXIT; + } + + if (mode == "init") { + return init(); + } else if (mode == "sign") { + if (m.empty()) goto ERR_EXIT; + return sign(m, id); + } else if (mode == "verify") { + if (m.empty()) goto ERR_EXIT; + return verify(m, id); + } else if (mode == "share") { + return share(n, k); + } else if (mode == "recover") { + if (ids.empty()) { + fprintf(stderr, "use -ids option. ex. share -ids 1 3 5\n"); + goto ERR_EXIT; + } + return recover(ids); + } else { + fprintf(stderr, "bad mode %s\n", mode.c_str()); + } +ERR_EXIT: + opt.usage(); + return 1; +} catch (std::exception& e) { + fprintf(stderr, "ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/bls/setvar.bat b/vendor/github.com/dexon-foundation/bls/setvar.bat index b45af24b9..0ff286ab8 100755 --- a/vendor/github.com/dexon-foundation/bls/setvar.bat +++ b/vendor/github.com/dexon-foundation/bls/setvar.bat @@ -1,6 +1,6 @@ @echo off call ..\mcl\setvar.bat -set CFLAGS=%CFLAGS% /I ..\mcl\include /I .\ +set CFLAGS=%CFLAGS% /I ..\mcl\include /I ./ set LDFLAGS=%LDFLAGS% /LIBPATH:..\mcl\lib echo CFLAGS=%CFLAGS% -echo LDFLAGS=%LDFLAGS%
\ No newline at end of file +echo LDFLAGS=%LDFLAGS% diff --git a/vendor/github.com/dexon-foundation/bls/src/bls_c384_256.cpp b/vendor/github.com/dexon-foundation/bls/src/bls_c384_256.cpp new file mode 100644 index 000000000..3dcb3e7d7 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/src/bls_c384_256.cpp @@ -0,0 +1,4 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#define MCLBN_FR_UNIT_SIZE 4 +#include "bls_c_impl.hpp" + diff --git a/vendor/github.com/dexon-foundation/bls/src/bls_c_impl.hpp b/vendor/github.com/dexon-foundation/bls/src/bls_c_impl.hpp index 16b79f913..b38c1ad06 100644 --- a/vendor/github.com/dexon-foundation/bls/src/bls_c_impl.hpp +++ b/vendor/github.com/dexon-foundation/bls/src/bls_c_impl.hpp @@ -3,30 +3,81 @@ #include <bls/bls.h> -#include "../mcl/src/bn_c_impl.hpp" +#if 1 +#include "mcl/impl/bn_c_impl.hpp" +#else +#if MCLBN_FP_UNIT_SIZE == 4 && MCLBN_FR_UNIT_SIZE == 4 +#include <mcl/bn256.hpp> +#elif MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 6 +#include <mcl/bn384.hpp> +#elif MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 4 +#include <mcl/bls12_381.hpp> +#elif MCLBN_FP_UNIT_SIZE == 8 && MCLBN_FR_UNIT_SIZE == 8 +#include <mcl/bn512.hpp> +#else + #error "not supported size" +#endif +#include <mcl/lagrange.hpp> +using namespace mcl::bn; +inline Fr *cast(mclBnFr *p) { return reinterpret_cast<Fr*>(p); } +inline const Fr *cast(const mclBnFr *p) { return reinterpret_cast<const Fr*>(p); } + +inline G1 *cast(mclBnG1 *p) { return reinterpret_cast<G1*>(p); } +inline const G1 *cast(const mclBnG1 *p) { return reinterpret_cast<const G1*>(p); } + +inline G2 *cast(mclBnG2 *p) { return reinterpret_cast<G2*>(p); } +inline const G2 *cast(const mclBnG2 *p) { return reinterpret_cast<const G2*>(p); } + +inline Fp12 *cast(mclBnGT *p) { return reinterpret_cast<Fp12*>(p); } +inline const Fp12 *cast(const mclBnGT *p) { return reinterpret_cast<const Fp12*>(p); } + +inline Fp6 *cast(uint64_t *p) { return reinterpret_cast<Fp6*>(p); } +inline const Fp6 *cast(const uint64_t *p) { return reinterpret_cast<const Fp6*>(p); } +#endif + +void Gmul(G1& z, const G1& x, const Fr& y) { G1::mul(z, x, y); } +void Gmul(G2& z, const G2& x, const Fr& y) { G2::mul(z, x, y); } +void GmulCT(G1& z, const G1& x, const Fr& y) { G1::mulCT(z, x, y); } +void GmulCT(G2& z, const G2& x, const Fr& y) { G2::mulCT(z, x, y); } /* BLS signature - e : G1 x G2 -> Fp12 + e : G1 x G2 -> GT Q in G2 ; fixed global parameter H : {str} -> G1 s : secret key sQ ; public key s H(m) ; signature of m verify ; e(sQ, H(m)) = e(Q, s H(m)) + + swap G1 and G2 if BLS_SWAP_G is defined + @note the current implementation does not support precomputed miller loop */ +#ifdef BLS_SWAP_G +static G1 g_P; +inline const G1& getBasePoint() { return g_P; } +#else static G2 g_Q; const size_t maxQcoeffN = 128; static mcl::FixedArray<Fp6, maxQcoeffN> g_Qcoeff; // precomputed Q -inline const G2& getQ() { return g_Q; } +inline const G2& getBasePoint() { return g_Q; } inline const mcl::FixedArray<Fp6, maxQcoeffN>& getQcoeff() { return g_Qcoeff; } +#endif int blsInitNotThreadSafe(int curve, int compiledTimeVar) { - int ret = mclBn_init(curve, compiledTimeVar); - if (ret < 0) return ret; + if (compiledTimeVar != MCLBN_COMPILED_TIME_VAR) { + return -(compiledTimeVar | (MCLBN_COMPILED_TIME_VAR * 100)); + } + const mcl::CurveParam& cp = mcl::getCurveParam(curve); bool b; + initPairing(&b, cp); + if (!b) return -1; + +#ifdef BLS_SWAP_G + mapToG1(&b, g_P, 1); +#else if (curve == MCL_BN254) { const char *Qx_BN254 = "11ccb44e77ac2c5dc32a6009594dbe331ec85a61290d6bbac8cc7ebb2dceb128 f204a14bbdac4a05be9a25176de827f2e60085668becdd4fc5fa914c9ee0d9a"; @@ -41,7 +92,7 @@ int blsInitNotThreadSafe(int curve, int compiledTimeVar) if (curve == MCL_BN254) { #include "./qcoeff-bn254.hpp" g_Qcoeff.resize(BN::param.precomputedQcoeffSize); - assert(g_Qcoeff.size() == CYBOZU_NUM_OF_ARRAY(tbl)); + assert(g_Qcoeff.size() == CYBOZU_NUM_OF_ARRAY(QcoeffTblBN254)); for (size_t i = 0; i < g_Qcoeff.size(); i++) { Fp6& x6 = g_Qcoeff[i]; for (size_t j = 0; j < 6; j++) { @@ -53,8 +104,9 @@ int blsInitNotThreadSafe(int curve, int compiledTimeVar) } } } else { - precomputeG2(&b, g_Qcoeff, getQ()); + precomputeG2(&b, g_Qcoeff, getBasePoint()); } +#endif if (!b) return -101; return 0; } @@ -103,26 +155,55 @@ static inline const mclBnG2 *cast(const G2* x) { return (const mclBnG2*)x; } void blsIdSetInt(blsId *id, int x) { - mclBnFr_setInt(&id->v, x); + *cast(&id->v) = x; } int blsSecretKeySetLittleEndian(blsSecretKey *sec, const void *buf, mclSize bufSize) { - return mclBnFr_setLittleEndian(&sec->v, buf, bufSize); + cast(&sec->v)->setArrayMask((const char *)buf, bufSize); + return 0; +} +int blsSecretKeySetLittleEndianMod(blsSecretKey *sec, const void *buf, mclSize bufSize) +{ + bool b; + cast(&sec->v)->setArray(&b, (const char *)buf, bufSize, mcl::fp::Mod); + return b ? 0 : -1; } void blsGetPublicKey(blsPublicKey *pub, const blsSecretKey *sec) { - mclBnG2_mul(&pub->v, cast(&getQ()), &sec->v); + Gmul(*cast(&pub->v), getBasePoint(), *cast(&sec->v)); } void blsSign(blsSignature *sig, const blsSecretKey *sec, const void *m, mclSize size) { +#ifdef BLS_SWAP_G + G2 Hm; + hashAndMapToG2(Hm, m, size); +#else G1 Hm; hashAndMapToG1(Hm, m, size); - mclBnG1_mulCT(&sig->v, cast(&Hm), &sec->v); +#endif + GmulCT(*cast(&sig->v), Hm, *cast(&sec->v)); } +#ifdef BLS_SWAP_G +/* + e(P, sHm) == e(sP, Hm) + <=> finalExp(ML(P, sHm) * e(-sP, Hm)) == 1 +*/ +bool isEqualTwoPairings(const G2& sHm, const G1& sP, const G2& Hm) +{ + GT e1, e2; + millerLoop(e1, getBasePoint(), sHm); + G1 neg_sP; + G1::neg(neg_sP, sP); + millerLoop(e2, neg_sP, Hm); + e1 *= e2; + finalExp(e1, e1); + return e1.isOne(); +} +#else /* e(P1, Q1) == e(P2, Q2) <=> finalExp(ML(P1, Q1)) == finalExp(ML(P2, Q2)) @@ -132,14 +213,20 @@ void blsSign(blsSignature *sig, const blsSecretKey *sec, const void *m, mclSize */ bool isEqualTwoPairings(const G1& P1, const Fp6* Q1coeff, const G1& P2, const G2& Q2) { - Fp12 e; + GT e; precomputedMillerLoop2mixed(e, P2, Q2, -P1, Q1coeff); finalExp(e, e); return e.isOne(); } +#endif int blsVerify(const blsSignature *sig, const blsPublicKey *pub, const void *m, mclSize size) { +#ifdef BLS_SWAP_G + G2 Hm; + hashAndMapToG2(Hm, m, size); + return isEqualTwoPairings(*cast(&sig->v), *cast(&pub->v), Hm); +#else G1 Hm; hashAndMapToG1(Hm, m, size); /* @@ -147,187 +234,238 @@ int blsVerify(const blsSignature *sig, const blsPublicKey *pub, const void *m, m e(sig, Q) = e(Hm, pub) */ return isEqualTwoPairings(*cast(&sig->v), getQcoeff().data(), Hm, *cast(&pub->v)); +#endif } mclSize blsIdSerialize(void *buf, mclSize maxBufSize, const blsId *id) { - return mclBnFr_serialize(buf, maxBufSize, &id->v); + return cast(&id->v)->serialize(buf, maxBufSize); } mclSize blsSecretKeySerialize(void *buf, mclSize maxBufSize, const blsSecretKey *sec) { - return mclBnFr_serialize(buf, maxBufSize, &sec->v); + return cast(&sec->v)->serialize(buf, maxBufSize); } mclSize blsPublicKeySerialize(void *buf, mclSize maxBufSize, const blsPublicKey *pub) { - return mclBnG2_serialize(buf, maxBufSize, &pub->v); + return cast(&pub->v)->serialize(buf, maxBufSize); } mclSize blsSignatureSerialize(void *buf, mclSize maxBufSize, const blsSignature *sig) { - return mclBnG1_serialize(buf, maxBufSize, &sig->v); + return cast(&sig->v)->serialize(buf, maxBufSize); } mclSize blsIdDeserialize(blsId *id, const void *buf, mclSize bufSize) { - return mclBnFr_deserialize(&id->v, buf, bufSize); + return cast(&id->v)->deserialize(buf, bufSize); } -mclSize blsSecretKeyDeserialize(blsSecretKey *sig, const void *buf, mclSize bufSize) +mclSize blsSecretKeyDeserialize(blsSecretKey *sec, const void *buf, mclSize bufSize) { - return mclBnFr_deserialize(&sig->v, buf, bufSize); + return cast(&sec->v)->deserialize(buf, bufSize); } mclSize blsPublicKeyDeserialize(blsPublicKey *pub, const void *buf, mclSize bufSize) { - return mclBnG2_deserialize(&pub->v, buf, bufSize); + return cast(&pub->v)->deserialize(buf, bufSize); } mclSize blsSignatureDeserialize(blsSignature *sig, const void *buf, mclSize bufSize) { - return mclBnG1_deserialize(&sig->v, buf, bufSize); + return cast(&sig->v)->deserialize(buf, bufSize); } int blsIdIsEqual(const blsId *lhs, const blsId *rhs) { - return mclBnFr_isEqual(&lhs->v, &rhs->v); + return *cast(&lhs->v) == *cast(&rhs->v); } int blsSecretKeyIsEqual(const blsSecretKey *lhs, const blsSecretKey *rhs) { - return mclBnFr_isEqual(&lhs->v, &rhs->v); + return *cast(&lhs->v) == *cast(&rhs->v); } int blsPublicKeyIsEqual(const blsPublicKey *lhs, const blsPublicKey *rhs) { - return mclBnG2_isEqual(&lhs->v, &rhs->v); + return *cast(&lhs->v) == *cast(&rhs->v); } int blsSignatureIsEqual(const blsSignature *lhs, const blsSignature *rhs) { - return mclBnG1_isEqual(&lhs->v, &rhs->v); + return *cast(&lhs->v) == *cast(&rhs->v); } int blsSecretKeyShare(blsSecretKey *sec, const blsSecretKey* msk, mclSize k, const blsId *id) { - return mclBn_FrEvaluatePolynomial(&sec->v, &msk->v, k, &id->v); + bool b; + mcl::evaluatePolynomial(&b, *cast(&sec->v), cast(&msk->v), k, *cast(&id->v)); + return b ? 0 : -1; } int blsPublicKeyShare(blsPublicKey *pub, const blsPublicKey *mpk, mclSize k, const blsId *id) { - return mclBn_G2EvaluatePolynomial(&pub->v, &mpk->v, k, &id->v); + bool b; + mcl::evaluatePolynomial(&b, *cast(&pub->v), cast(&mpk->v), k, *cast(&id->v)); + return b ? 0 : -1; } int blsSecretKeyRecover(blsSecretKey *sec, const blsSecretKey *secVec, const blsId *idVec, mclSize n) { - return mclBn_FrLagrangeInterpolation(&sec->v, &idVec->v, &secVec->v, n); + bool b; + mcl::LagrangeInterpolation(&b, *cast(&sec->v), cast(&idVec->v), cast(&secVec->v), n); + return b ? 0 : -1; } int blsPublicKeyRecover(blsPublicKey *pub, const blsPublicKey *pubVec, const blsId *idVec, mclSize n) { - return mclBn_G2LagrangeInterpolation(&pub->v, &idVec->v, &pubVec->v, n); + bool b; + mcl::LagrangeInterpolation(&b, *cast(&pub->v), cast(&idVec->v), cast(&pubVec->v), n); + return b ? 0 : -1; } int blsSignatureRecover(blsSignature *sig, const blsSignature *sigVec, const blsId *idVec, mclSize n) { - return mclBn_G1LagrangeInterpolation(&sig->v, &idVec->v, &sigVec->v, n); + bool b; + mcl::LagrangeInterpolation(&b, *cast(&sig->v), cast(&idVec->v), cast(&sigVec->v), n); + return b ? 0 : -1; } void blsSecretKeyAdd(blsSecretKey *sec, const blsSecretKey *rhs) { - mclBnFr_add(&sec->v, &sec->v, &rhs->v); + *cast(&sec->v) += *cast(&rhs->v); } void blsPublicKeyAdd(blsPublicKey *pub, const blsPublicKey *rhs) { - mclBnG2_add(&pub->v, &pub->v, &rhs->v); + *cast(&pub->v) += *cast(&rhs->v); } void blsSignatureAdd(blsSignature *sig, const blsSignature *rhs) { - mclBnG1_add(&sig->v, &sig->v, &rhs->v); + *cast(&sig->v) += *cast(&rhs->v); } void blsSignatureVerifyOrder(int doVerify) { - mclBn_verifyOrderG1(doVerify); +#ifdef BLS_SWAP_G + verifyOrderG2(doVerify != 0); +#else + verifyOrderG1(doVerify != 0); +#endif } void blsPublicKeyVerifyOrder(int doVerify) { - mclBn_verifyOrderG2(doVerify); +#ifdef BLS_SWAP_G + verifyOrderG1(doVerify != 0); +#else + verifyOrderG2(doVerify != 0); +#endif } int blsSignatureIsValidOrder(const blsSignature *sig) { - return mclBnG1_isValidOrder(&sig->v); + return cast(&sig->v)->isValidOrder(); } int blsPublicKeyIsValidOrder(const blsPublicKey *pub) { - return mclBnG2_isValidOrder(&pub->v); + return cast(&pub->v)->isValidOrder(); } #ifndef BLS_MINIMUM_API -inline bool toG1(G1& Hm, const void *h, mclSize size) +template<class G> +inline bool toG(G& Hm, const void *h, mclSize size) { Fp t; t.setArrayMask((const char *)h, size); bool b; +#ifdef BLS_SWAP_G + BN::mapToG2(&b, Hm, Fp2(t, 0)); +#else BN::mapToG1(&b, Hm, t); +#endif return b; } int blsVerifyAggregatedHashes(const blsSignature *aggSig, const blsPublicKey *pubVec, const void *hVec, size_t sizeofHash, mclSize n) { if (n == 0) return 0; + GT e1, e2; + const char *ph = (const char*)hVec; +#ifdef BLS_SWAP_G + millerLoop(e1, getBasePoint(), -*cast(&aggSig->v)); + G2 h; + if (!toG(h, &ph[0], sizeofHash)) return 0; + BN::millerLoop(e2, *cast(&pubVec[0].v), h); + e1 *= e2; + for (size_t i = 1; i < n; i++) { + if (!toG(h, &ph[i * sizeofHash], sizeofHash)) return 0; + millerLoop(e2, *cast(&pubVec[i].v), h); + e1 *= e2; + } +#else /* e(aggSig, Q) = prod_i e(hVec[i], pubVec[i]) <=> finalExp(ML(-aggSig, Q) * prod_i ML(hVec[i], pubVec[i])) == 1 */ - GT e1, e2; BN::precomputedMillerLoop(e1, -*cast(&aggSig->v), g_Qcoeff.data()); - const char *ph = (const char*)hVec; G1 h; - if (!toG1(h, &ph[0], sizeofHash)) return 0; + if (!toG(h, &ph[0], sizeofHash)) return 0; BN::millerLoop(e2, h, *cast(&pubVec[0].v)); e1 *= e2; for (size_t i = 1; i < n; i++) { - if (!toG1(h, &ph[i * sizeofHash], sizeofHash)) return 0; + if (!toG(h, &ph[i * sizeofHash], sizeofHash)) return 0; BN::millerLoop(e2, h, *cast(&pubVec[i].v)); e1 *= e2; } +#endif BN::finalExp(e1, e1); return e1.isOne(); } int blsSignHash(blsSignature *sig, const blsSecretKey *sec, const void *h, mclSize size) { +#ifdef BLS_SWAP_G + G2 Hm; +#else G1 Hm; - if (!toG1(Hm, h, size)) return -1; - mclBnG1_mulCT(&sig->v, cast(&Hm), &sec->v); +#endif + if (!toG(Hm, h, size)) return -1; + GmulCT(*cast(&sig->v), Hm, *cast(&sec->v)); return 0; } +int blsVerifyPairing(const blsSignature *X, const blsSignature *Y, const blsPublicKey *pub) +{ +#ifdef BLS_SWAP_G + return isEqualTwoPairings(*cast(&X->v), *cast(&pub->v), *cast(&Y->v)); +#else + return isEqualTwoPairings(*cast(&X->v), getQcoeff().data(), *cast(&Y->v), *cast(&pub->v)); +#endif +} + int blsVerifyHash(const blsSignature *sig, const blsPublicKey *pub, const void *h, mclSize size) { - G1 Hm; - if (!toG1(Hm, h, size)) return 0; - return isEqualTwoPairings(*cast(&sig->v), getQcoeff().data(), Hm, *cast(&pub->v)); + blsSignature Hm; + if (!toG(*cast(&Hm.v), h, size)) return 0; + return blsVerifyPairing(sig, &Hm, pub); } void blsSecretKeySub(blsSecretKey *sec, const blsSecretKey *rhs) { - mclBnFr_sub(&sec->v, &sec->v, &rhs->v); + *cast(&sec->v) -= *cast(&rhs->v); } void blsPublicKeySub(blsPublicKey *pub, const blsPublicKey *rhs) { - mclBnG2_sub(&pub->v, &pub->v, &rhs->v); + *cast(&pub->v) -= *cast(&rhs->v); } void blsSignatureSub(blsSignature *sig, const blsSignature *rhs) { - mclBnG1_sub(&sig->v, &sig->v, &rhs->v); + *cast(&sig->v) -= *cast(&rhs->v); } + mclSize blsGetOpUnitSize() // FpUint64Size { return Fp::getUnitSize() * sizeof(mcl::fp::Unit) / sizeof(uint64_t); @@ -345,52 +483,67 @@ int blsGetFieldOrder(char *buf, mclSize maxBufSize) int blsGetG1ByteSize() { - return mclBn_getG1ByteSize(); + return (int)Fp::getByteSize(); } int blsGetFrByteSize() { - return mclBn_getFrByteSize(); + return (int)Fr::getByteSize(); } +#ifdef BLS_SWAP_G +void blsGetGeneratorOfG1(blsPublicKey *pub) +{ + *cast(&pub->v) = getBasePoint(); +} +#else void blsGetGeneratorOfG2(blsPublicKey *pub) { - *(G2*)pub = getQ(); + *cast(&pub->v) = getBasePoint(); } +#endif int blsIdSetDecStr(blsId *id, const char *buf, mclSize bufSize) { - return mclBnFr_setStr(&id->v, buf, bufSize, 10); + return cast(&id->v)->deserialize(buf, bufSize, 10) > 0 ? 0 : -1; } int blsIdSetHexStr(blsId *id, const char *buf, mclSize bufSize) { - return mclBnFr_setStr(&id->v, buf, bufSize, 16); + return cast(&id->v)->deserialize(buf, bufSize, 16) > 0 ? 0 : -1; } int blsIdSetLittleEndian(blsId *id, const void *buf, mclSize bufSize) { - return mclBnFr_setLittleEndian(&id->v, buf, bufSize); + cast(&id->v)->setArrayMask((const char *)buf, bufSize); + return 0; } mclSize blsIdGetDecStr(char *buf, mclSize maxBufSize, const blsId *id) { - return mclBnFr_getStr(buf, maxBufSize, &id->v, 10); + return cast(&id->v)->getStr(buf, maxBufSize, 10); } mclSize blsIdGetHexStr(char *buf, mclSize maxBufSize, const blsId *id) { - return mclBnFr_getStr(buf, maxBufSize, &id->v, 16); + return cast(&id->v)->getStr(buf, maxBufSize, 16); } int blsHashToSecretKey(blsSecretKey *sec, const void *buf, mclSize bufSize) { - return mclBnFr_setHashOf(&sec->v, buf, bufSize); + cast(&sec->v)->setHashOf(buf, bufSize); + return 0; } #ifndef MCL_DONT_USE_CSPRNG int blsSecretKeySetByCSPRNG(blsSecretKey *sec) { - return mclBnFr_setByCSPRNG(&sec->v); + bool b; + cast(&sec->v)->setByCSPRNG(&b); + return b ? 0 : -1; +} +void blsSetRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)) +{ + mcl::fp::RandGen::setRandFunc(self, readFunc); } #endif @@ -399,7 +552,7 @@ void blsGetPop(blsSignature *sig, const blsSecretKey *sec) blsPublicKey pub; blsGetPublicKey(&pub, sec); char buf[1024]; - mclSize n = mclBnG2_serialize(buf, sizeof(buf), &pub.v); + mclSize n = cast(&pub.v)->serialize(buf, sizeof(buf)); assert(n); blsSign(sig, sec, buf, n); } @@ -407,54 +560,54 @@ void blsGetPop(blsSignature *sig, const blsSecretKey *sec) int blsVerifyPop(const blsSignature *sig, const blsPublicKey *pub) { char buf[1024]; - mclSize n = mclBnG2_serialize(buf, sizeof(buf), &pub->v); + mclSize n = cast(&pub->v)->serialize(buf, sizeof(buf)); if (n == 0) return 0; return blsVerify(sig, pub, buf, n); } mclSize blsIdGetLittleEndian(void *buf, mclSize maxBufSize, const blsId *id) { - return mclBnFr_serialize(buf, maxBufSize, &id->v); + return cast(&id->v)->serialize(buf, maxBufSize); } int blsSecretKeySetDecStr(blsSecretKey *sec, const char *buf, mclSize bufSize) { - return mclBnFr_setStr(&sec->v, buf, bufSize, 10); + return cast(&sec->v)->deserialize(buf, bufSize, 10) > 0 ? 0 : -1; } int blsSecretKeySetHexStr(blsSecretKey *sec, const char *buf, mclSize bufSize) { - return mclBnFr_setStr(&sec->v, buf, bufSize, 16); + return cast(&sec->v)->deserialize(buf, bufSize, 16) > 0 ? 0 : -1; } mclSize blsSecretKeyGetLittleEndian(void *buf, mclSize maxBufSize, const blsSecretKey *sec) { - return mclBnFr_serialize(buf, maxBufSize, &sec->v); + return cast(&sec->v)->serialize(buf, maxBufSize); } mclSize blsSecretKeyGetDecStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec) { - return mclBnFr_getStr(buf, maxBufSize, &sec->v, 10); + return cast(&sec->v)->getStr(buf, maxBufSize, 10); } mclSize blsSecretKeyGetHexStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec) { - return mclBnFr_getStr(buf, maxBufSize, &sec->v, 16); + return cast(&sec->v)->getStr(buf, maxBufSize, 16); } int blsPublicKeySetHexStr(blsPublicKey *pub, const char *buf, mclSize bufSize) { - return mclBnG2_setStr(&pub->v, buf, bufSize, 16); + return cast(&pub->v)->deserialize(buf, bufSize, 16) > 0 ? 0 : -1; } mclSize blsPublicKeyGetHexStr(char *buf, mclSize maxBufSize, const blsPublicKey *pub) { - return mclBnG2_getStr(buf, maxBufSize, &pub->v, 16); + return cast(&pub->v)->getStr(buf, maxBufSize, 16); } int blsSignatureSetHexStr(blsSignature *sig, const char *buf, mclSize bufSize) { - return mclBnG1_setStr(&sig->v, buf, bufSize, 16); + return cast(&sig->v)->deserialize(buf, bufSize, 16) > 0 ? 0 : -1; } mclSize blsSignatureGetHexStr(char *buf, mclSize maxBufSize, const blsSignature *sig) { - return mclBnG1_getStr(buf, maxBufSize, &sig->v, 16); + return cast(&sig->v)->getStr(buf, maxBufSize, 16); } void blsDHKeyExchange(blsPublicKey *out, const blsSecretKey *sec, const blsPublicKey *pub) { - mclBnG2_mulCT(&out->v, &pub->v, &sec->v); + GmulCT(*cast(&out->v), *cast(&pub->v), *cast(&sec->v)); } #endif diff --git a/vendor/github.com/dexon-foundation/bls/test/bls256_test.cpp b/vendor/github.com/dexon-foundation/bls/test/bls256_test.cpp new file mode 100644 index 000000000..e53a87057 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls256_test.cpp @@ -0,0 +1,3 @@ +#define MCLBN_FP_UNIT_SIZE 4 +#include "bls_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/bls/test/bls384_256_test.cpp b/vendor/github.com/dexon-foundation/bls/test/bls384_256_test.cpp new file mode 100644 index 000000000..ea8126567 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls384_256_test.cpp @@ -0,0 +1,4 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#define MCLBN_FR_UNIT_SIZE 4 +#include "bls_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/bls/test/bls384_test.cpp b/vendor/github.com/dexon-foundation/bls/test/bls384_test.cpp new file mode 100644 index 000000000..2212f8e6b --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls384_test.cpp @@ -0,0 +1,3 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#include "bls_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/bls/test/bls_c256_test.cpp b/vendor/github.com/dexon-foundation/bls/test/bls_c256_test.cpp new file mode 100644 index 000000000..8613720b4 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls_c256_test.cpp @@ -0,0 +1,2 @@ +#define MCLBN_FP_UNIT_SIZE 4 +#include "bls_c_test.hpp" diff --git a/vendor/github.com/dexon-foundation/bls/test/bls_c384_256_test.cpp b/vendor/github.com/dexon-foundation/bls/test/bls_c384_256_test.cpp new file mode 100644 index 000000000..6f153f9d8 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls_c384_256_test.cpp @@ -0,0 +1,3 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#define MCLBN_FR_UNIT_SIZE 4 +#include "bls_c_test.hpp" diff --git a/vendor/github.com/dexon-foundation/bls/test/bls_c384_test.cpp b/vendor/github.com/dexon-foundation/bls/test/bls_c384_test.cpp new file mode 100644 index 000000000..b6886dd04 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls_c384_test.cpp @@ -0,0 +1,2 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#include "bls_c_test.hpp" diff --git a/vendor/github.com/dexon-foundation/bls/test/bls_c_test.hpp b/vendor/github.com/dexon-foundation/bls/test/bls_c_test.hpp new file mode 100644 index 000000000..e9b6e6302 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls_c_test.hpp @@ -0,0 +1,437 @@ +#include <cybozu/test.hpp> +#include <cybozu/inttype.hpp> +#include <bls/bls.h> +#include <string.h> +#include <cybozu/benchmark.hpp> +#include <mcl/gmp_util.hpp> + +size_t pubSize(size_t FrSize) +{ +#ifdef BLS_SWAP_G + return FrSize; +#else + return FrSize * 2; +#endif +} +size_t sigSize(size_t FrSize) +{ +#ifdef BLS_SWAP_G + return FrSize * 2; +#else + return FrSize; +#endif +} + +void bls_use_stackTest() +{ + blsSecretKey sec; + blsPublicKey pub; + blsSignature sig; + const char *msg = "this is a pen"; + const size_t msgSize = strlen(msg); + + blsSecretKeySetByCSPRNG(&sec); + + blsGetPublicKey(&pub, &sec); + + blsSign(&sig, &sec, msg, msgSize); + + CYBOZU_TEST_ASSERT(blsVerify(&sig, &pub, msg, msgSize)); +} + +void blsDataTest() +{ + const char *msg = "test test"; + const size_t msgSize = strlen(msg); + const size_t FrSize = blsGetFrByteSize(); + const size_t FpSize = blsGetG1ByteSize(); + blsSecretKey sec1, sec2; + blsSecretKeySetByCSPRNG(&sec1); + char buf[1024]; + size_t n; + size_t ret; + n = blsSecretKeyGetHexStr(buf, sizeof(buf), &sec1); + CYBOZU_TEST_ASSERT(0 < n && n <= FrSize * 2); + ret = blsSecretKeySetHexStr(&sec2, buf, n); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec1, &sec2)); + + memset(&sec2, 0, sizeof(sec2)); + n = blsSecretKeySerialize(buf, sizeof(buf), &sec1); + CYBOZU_TEST_EQUAL(n, FrSize); + ret = blsSecretKeyDeserialize(&sec2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec1, &sec2)); + + blsPublicKey pub1, pub2; + blsGetPublicKey(&pub1, &sec1); + n = blsPublicKeySerialize(buf, sizeof(buf), &pub1); + CYBOZU_TEST_EQUAL(n, pubSize(FpSize)); + ret = blsPublicKeyDeserialize(&pub2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsPublicKeyIsEqual(&pub1, &pub2)); + blsSignature sig1, sig2; + blsSign(&sig1, &sec1, msg, msgSize); + n = blsSignatureSerialize(buf, sizeof(buf), &sig1); + CYBOZU_TEST_EQUAL(n, sigSize(FpSize)); + ret = blsSignatureDeserialize(&sig2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsSignatureIsEqual(&sig1, &sig2)); +} + +void blsOrderTest(const char *curveOrder/*Fr*/, const char *fieldOrder/*Fp*/) +{ + char buf[1024]; + size_t len; + len = blsGetCurveOrder(buf, sizeof(buf)); + CYBOZU_TEST_ASSERT(len > 0); + CYBOZU_TEST_EQUAL(buf, curveOrder); + len = blsGetFieldOrder(buf, sizeof(buf)); + CYBOZU_TEST_ASSERT(len > 0); + CYBOZU_TEST_EQUAL(buf, fieldOrder); +} + +#if !defined(DISABLE_THREAD_TEST) || defined(__clang__) +#if defined(CYBOZU_CPP_VERSION) && CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 +#include <thread> +#include <vector> +struct Thread { + std::unique_ptr<std::thread> t; + Thread() : t() {} + ~Thread() + { + if (t) { + t->join(); + } + } + template<class F> + void run(F func, int p1, int p2) + { + t.reset(new std::thread(func, p1, p2)); + } +}; + +CYBOZU_TEST_AUTO(multipleInit) +{ + const size_t n = 100; + { + std::vector<Thread> vt(n); + for (size_t i = 0; i < n; i++) { + vt[i].run(blsInit, MCL_BN254, MCLBN_COMPILED_TIME_VAR); + } + } + CYBOZU_TEST_EQUAL(blsGetOpUnitSize(), 4u); +#if MCLBN_FP_UNIT_SIZE == 6 + { + std::vector<Thread> vt(n); + for (size_t i = 0; i < n; i++) { + vt[i].run(blsInit, MCL_BLS12_381, MCLBN_COMPILED_TIME_VAR); + } + } + CYBOZU_TEST_EQUAL(blsGetOpUnitSize(), 6u); +#endif +} +#endif +#endif + +void blsSerializeTest() +{ + const size_t FrSize = blsGetFrByteSize(); + const size_t FpSize = blsGetG1ByteSize(); + printf("FrSize=%d, FpSize=%d\n", (int)FrSize, (int)FpSize); + blsId id1, id2; + blsSecretKey sec1, sec2; + blsPublicKey pub1, pub2; + blsSignature sig1, sig2; + char buf[1024]; + size_t n; + size_t expectSize; + size_t ret; + const char dummyChar = '1'; + + // Id + expectSize = FrSize; + blsIdSetInt(&id1, -1); + n = blsIdSerialize(buf, sizeof(buf), &id1); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = blsIdDeserialize(&id2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsIdIsEqual(&id1, &id2)); + + ret = blsIdDeserialize(&id2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&id2, 0, sizeof(id2)); + buf[n] = dummyChar; + ret = blsIdDeserialize(&id2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsIdIsEqual(&id1, &id2)); + + n = blsIdSerialize(buf, expectSize, &id1); + CYBOZU_TEST_EQUAL(n, expectSize); + + // SecretKey + expectSize = FrSize; + blsSecretKeySetDecStr(&sec1, "-1", 2); + n = blsSecretKeySerialize(buf, sizeof(buf), &sec1); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = blsSecretKeyDeserialize(&sec2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec1, &sec2)); + + ret = blsSecretKeyDeserialize(&sec2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&sec2, 0, sizeof(sec2)); + buf[n] = dummyChar; + ret = blsSecretKeyDeserialize(&sec2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec1, &sec2)); + + n = blsSecretKeySerialize(buf, expectSize, &sec1); + CYBOZU_TEST_EQUAL(n, expectSize); + + // PublicKey + expectSize = pubSize(FpSize); + blsGetPublicKey(&pub1, &sec1); + n = blsPublicKeySerialize(buf, sizeof(buf), &pub1); + CYBOZU_TEST_EQUAL(n, expectSize); + CYBOZU_TEST_ASSERT(blsPublicKeyIsValidOrder(&pub1)); + + ret = blsPublicKeyDeserialize(&pub2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsPublicKeyIsEqual(&pub1, &pub2)); + + ret = blsPublicKeyDeserialize(&pub2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&pub2, 0, sizeof(pub2)); + buf[n] = dummyChar; + ret = blsPublicKeyDeserialize(&pub2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsPublicKeyIsEqual(&pub1, &pub2)); + + n = blsPublicKeySerialize(buf, expectSize, &pub1); + CYBOZU_TEST_EQUAL(n, expectSize); + + // Signature +#ifdef BLS_SWAP_G + expectSize = FpSize * 2; +#else + expectSize = FpSize; +#endif + blsSign(&sig1, &sec1, "abc", 3); + n = blsSignatureSerialize(buf, sizeof(buf), &sig1); + CYBOZU_TEST_EQUAL(n, expectSize); + CYBOZU_TEST_ASSERT(blsSignatureIsValidOrder(&sig1)); + + ret = blsSignatureDeserialize(&sig2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsSignatureIsEqual(&sig1, &sig2)); + + ret = blsSignatureDeserialize(&sig2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&sig2, 0, sizeof(sig2)); + buf[n] = dummyChar; + ret = blsSignatureDeserialize(&sig2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(blsSignatureIsEqual(&sig1, &sig2)); + + n = blsSignatureSerialize(buf, expectSize, &sig1); + CYBOZU_TEST_EQUAL(n, expectSize); +} + +void blsVerifyOrderTest() +{ + puts("blsVerifyOrderTest"); +#ifdef BLS_SWAP_G + const uint8_t Qs[] = +#else + const uint8_t Ps[] = +#endif + { +0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + }; +#ifdef BLS_SWAP_G + const uint8_t Ps[] = +#else + const uint8_t Qs[] = +#endif + { +0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + }; + size_t n; + blsPublicKey pub; + n = blsPublicKeyDeserialize(&pub, Ps, sizeof(Ps)); + CYBOZU_TEST_EQUAL(n, 0); + blsPublicKeyVerifyOrder(0); + n = blsPublicKeyDeserialize(&pub, Ps, sizeof(Ps)); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_ASSERT(!blsPublicKeyIsValidOrder(&pub)); + blsPublicKeyVerifyOrder(1); + + blsSignature sig; + n = blsSignatureDeserialize(&sig, Qs, sizeof(Qs)); + CYBOZU_TEST_EQUAL(n, 0); + blsSignatureVerifyOrder(0); + n = blsSignatureDeserialize(&sig, Qs, sizeof(Qs)); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_ASSERT(!blsSignatureIsValidOrder(&sig)); + blsSignatureVerifyOrder(1); +} + +void blsAddSubTest() +{ + blsSecretKey sec[3]; + blsPublicKey pub[3]; + blsSignature sig[3]; + const char *msg = "this is a pen"; + const size_t msgSize = strlen(msg); + + const char *secHexStr[8] = { "12", "34" }; + for (int i = 0; i < 2; i++) { + blsSecretKeySetHexStr(&sec[i], secHexStr[i], strlen(secHexStr[i])); + blsGetPublicKey(&pub[i], &sec[i]); + blsSign(&sig[i], &sec[i], msg, msgSize); + } + sec[2] = sec[0]; + blsSecretKeyAdd(&sec[2], &sec[1]); + char buf[1024]; + size_t n = blsSecretKeyGetHexStr(buf, sizeof(buf), &sec[2]); + CYBOZU_TEST_EQUAL(n, 2); + CYBOZU_TEST_EQUAL(buf, "46"); // "12" + "34" + + pub[2] = pub[0]; + blsPublicKeyAdd(&pub[2], &pub[1]); + sig[2] = sig[0]; + blsSignatureAdd(&sig[2], &sig[1]); // sig[2] = sig[0] + sig[1] + blsSignature sig2; + blsSign(&sig2, &sec[2], msg, msgSize); // sig2 = signature by sec[2] + CYBOZU_TEST_ASSERT(blsSignatureIsEqual(&sig2, &sig[2])); + CYBOZU_TEST_ASSERT(blsVerify(&sig[2], &pub[2], msg, msgSize)); // verify by pub[2] + + blsSecretKeySub(&sec[2], &sec[1]); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec[2], &sec[0])); + blsPublicKeySub(&pub[2], &pub[1]); + CYBOZU_TEST_ASSERT(blsPublicKeyIsEqual(&pub[2], &pub[0])); + blsSignatureSub(&sig[2], &sig[1]); + CYBOZU_TEST_ASSERT(blsSignatureIsEqual(&sig[2], &sig[0])); +} + +void blsTrivialShareTest() +{ + blsSecretKey sec1, sec2; + blsPublicKey pub1, pub2; + blsId id; + blsIdSetInt(&id, 123); + + blsSecretKeySetByCSPRNG(&sec1); + blsGetPublicKey(&pub1, &sec1); + int ret; + + memset(&sec2, 0, sizeof(sec2)); + ret = blsSecretKeyShare(&sec2, &sec1, 1, &id); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec1, &sec2)); + memset(&sec2, 0, sizeof(sec2)); + ret = blsSecretKeyRecover(&sec2, &sec1, &id, 1); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(blsSecretKeyIsEqual(&sec1, &sec2)); + + memset(&pub2, 0, sizeof(pub2)); + ret = blsPublicKeyShare(&pub2, &pub1, 1, &id); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(blsPublicKeyIsEqual(&pub1, &pub2)); + memset(&pub2, 0, sizeof(pub2)); + ret = blsPublicKeyRecover(&pub2, &pub1, &id, 1); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(blsPublicKeyIsEqual(&pub1, &pub2)); +} + +void modTest(const char *rStr) +{ + unsigned char buf[1024] = {}; + int ret; + blsSecretKey sec; + const size_t maxByte = 64; // 512-bit + memset(buf, 0xff, maxByte); + ret = blsSecretKeySetLittleEndianMod(&sec, buf, maxByte); + CYBOZU_TEST_EQUAL(ret, 0); + const mpz_class x = (mpz_class(1) << (maxByte * 8)) - 1; // 512-bit 0xff....ff + const mpz_class r(rStr); + size_t n = blsSecretKeySerialize(buf, sizeof(buf), &sec); + CYBOZU_TEST_ASSERT(n > 0); + // serialized data to mpz_class + mpz_class y = 0; + for (size_t i = 0; i < n; i++) { + y <<= 8; + y += buf[n - 1 - i]; + } + CYBOZU_TEST_EQUAL(y, x % r); +} + +void blsBench() +{ + blsSecretKey sec; + blsPublicKey pub; + blsSignature sig; + const char *msg = "this is a pen"; + const size_t msgSize = strlen(msg); + + blsSecretKeySetByCSPRNG(&sec); + + blsGetPublicKey(&pub, &sec); + + CYBOZU_BENCH_C("sign", 10000, blsSign, &sig, &sec, msg, msgSize); + CYBOZU_BENCH_C("verify", 1000, blsVerify, &sig, &pub, msg, msgSize); +} + +CYBOZU_TEST_AUTO(all) +{ + const struct { + int curveType; + const char *r; + const char *p; + } tbl[] = { + { + MCL_BN254, + "16798108731015832284940804142231733909759579603404752749028378864165570215949", + "16798108731015832284940804142231733909889187121439069848933715426072753864723", + }, +#if MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 6 + { + MCL_BN381_1, + "5540996953667913971058039301942914304734176495422447785042938606876043190415948413757785063597439175372845535461389", + "5540996953667913971058039301942914304734176495422447785045292539108217242186829586959562222833658991069414454984723", + }, +#endif +#if MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE >= 4 + { + MCL_BLS12_381, + "52435875175126190479447740508185965837690552500527637822603658699938581184513", + "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787", + }, +#endif + }; + for (size_t i = 0; i < sizeof(tbl) / sizeof(tbl[0]); i++) { + printf("i=%d\n", (int)i); + int ret = blsInit(tbl[i].curveType, MCLBN_COMPILED_TIME_VAR); + CYBOZU_TEST_EQUAL(ret, 0); + if (ret) { + printf("ERR %d\n", ret); + exit(1); + } + bls_use_stackTest(); + blsDataTest(); + blsOrderTest(tbl[i].r, tbl[i].p); + blsSerializeTest(); + if (tbl[i].curveType == MCL_BLS12_381) blsVerifyOrderTest(); + blsAddSubTest(); + blsTrivialShareTest(); + modTest(tbl[i].r); + blsBench(); + } +} diff --git a/vendor/github.com/dexon-foundation/bls/test/bls_test.hpp b/vendor/github.com/dexon-foundation/bls/test/bls_test.hpp new file mode 100644 index 000000000..346fafe15 --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/bls_test.hpp @@ -0,0 +1,545 @@ +#include <bls/bls.hpp> +#include <cybozu/test.hpp> +#include <cybozu/inttype.hpp> +#include <iostream> +#include <sstream> +#include <cybozu/benchmark.hpp> +#include <cybozu/sha2.hpp> + +template<class T> +void streamTest(const T& t) +{ + std::ostringstream oss; + oss << t; + std::istringstream iss(oss.str()); + T t2; + iss >> t2; + CYBOZU_TEST_EQUAL(t, t2); +} + +template<class T> +void testSetForBN254() +{ + /* + mask value to be less than r if the value >= (1 << (192 + 62)) + */ + const uint64_t fff = uint64_t(-1); + const uint64_t one = uint64_t(1); + const struct { + uint64_t in; + uint64_t expected; + } tbl[] = { + { fff, (one << 61) - 1 }, // masked with (1 << 61) - 1 + { one << 62, 0 }, // masked + { (one << 62) | (one << 61), (one << 61) }, // masked + { (one << 61) - 1, (one << 61) - 1 }, // same + }; + T t1, t2; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + uint64_t v1[] = { fff, fff, fff, tbl[i].in }; + uint64_t v2[] = { fff, fff, fff, tbl[i].expected }; + t1.set(v1); + t2.set(v2); + CYBOZU_TEST_EQUAL(t1, t2); + } +} + +void testForBN254() +{ + CYBOZU_TEST_EQUAL(bls::getOpUnitSize(), 4); + bls::Id id; + CYBOZU_TEST_ASSERT(id.isZero()); + id = 5; + CYBOZU_TEST_EQUAL(id, 5); + { + const uint64_t id1[] = { 1, 2, 3, 4 }; + id.set(id1); + std::ostringstream os; + os << id; + CYBOZU_TEST_EQUAL(os.str(), "0x4000000000000000300000000000000020000000000000001"); + } + testSetForBN254<bls::Id>(); + testSetForBN254<bls::SecretKey>(); +} + +void hashTest(int type) +{ + bls::SecretKey sec; + sec.init(); + bls::PublicKey pub; + sec.getPublicKey(pub); + const std::string h = "\x01\x02\x03"; + bls::Signature sig; + sec.signHash(sig, h); + CYBOZU_TEST_ASSERT(sig.verifyHash(pub, h)); + CYBOZU_TEST_ASSERT(!sig.verifyHash(pub, "\x01\x02\04")); + if (type == MCL_BN254) { + CYBOZU_TEST_EXCEPTION(sec.signHash(sig, "", 0), std::exception); + CYBOZU_TEST_EXCEPTION(sec.signHash(sig, "\x00", 1), std::exception); + CYBOZU_TEST_EXCEPTION(sec.signHash(sig, "\x00\x00", 2), std::exception); +#ifndef BLS_SWAP_G + const uint64_t c1[] = { 0x0c00000000000004ull, 0xcf0f000000000006ull, 0x26cd890000000003ull, 0x2523648240000001ull }; + const uint64_t mc1[] = { 0x9b0000000000000full, 0x921200000000000dull, 0x9366c48000000004ull }; + CYBOZU_TEST_EXCEPTION(sec.signHash(sig, c1, 32), std::exception); + CYBOZU_TEST_EXCEPTION(sec.signHash(sig, mc1, 24), std::exception); +#endif + } +} + +void blsTest() +{ + bls::SecretKey sec; + sec.init(); + streamTest(sec); + bls::PublicKey pub; + sec.getPublicKey(pub); + streamTest(pub); + for (int i = 0; i < 5; i++) { + std::string m = "hello"; + m += char('0' + i); + bls::Signature sig; + sec.sign(sig, m); + CYBOZU_TEST_ASSERT(sig.verify(pub, m)); + CYBOZU_TEST_ASSERT(!sig.verify(pub, m + "a")); + streamTest(sig); + CYBOZU_BENCH_C("sign", 10000, sec.sign, sig, m); + CYBOZU_BENCH_C("verify", 1000, sig.verify, pub, m); + } +} + +void k_of_nTest() +{ + const std::string m = "abc"; + const int n = 5; + const int k = 3; + bls::SecretKey sec0; + sec0.init(); + bls::Signature sig0; + sec0.sign(sig0, m); + bls::PublicKey pub0; + sec0.getPublicKey(pub0); + CYBOZU_TEST_ASSERT(sig0.verify(pub0, m)); + + bls::SecretKeyVec msk; + sec0.getMasterSecretKey(msk, k); + + bls::SecretKeyVec allPrvVec(n); + bls::IdVec allIdVec(n); + for (int i = 0; i < n; i++) { + int id = i + 1; + allPrvVec[i].set(msk, id); + allIdVec[i] = id; + + bls::SecretKey p; + p.set(msk.data(), k, id); + CYBOZU_TEST_EQUAL(allPrvVec[i], p); + } + + bls::SignatureVec allSigVec(n); + for (int i = 0; i < n; i++) { + CYBOZU_TEST_ASSERT(allPrvVec[i] != sec0); + allPrvVec[i].sign(allSigVec[i], m); + bls::PublicKey pub; + allPrvVec[i].getPublicKey(pub); + CYBOZU_TEST_ASSERT(pub != pub0); + CYBOZU_TEST_ASSERT(allSigVec[i].verify(pub, m)); + } + + /* + 3-out-of-n + can recover + */ + bls::SecretKeyVec secVec(3); + bls::IdVec idVec(3); + for (int a = 0; a < n; a++) { + secVec[0] = allPrvVec[a]; + idVec[0] = allIdVec[a]; + for (int b = a + 1; b < n; b++) { + secVec[1] = allPrvVec[b]; + idVec[1] = allIdVec[b]; + for (int c = b + 1; c < n; c++) { + secVec[2] = allPrvVec[c]; + idVec[2] = allIdVec[c]; + bls::SecretKey sec; + sec.recover(secVec, idVec); + CYBOZU_TEST_EQUAL(sec, sec0); + bls::SecretKey sec2; + sec2.recover(secVec.data(), idVec.data(), secVec.size()); + CYBOZU_TEST_EQUAL(sec, sec2); + } + } + } + { + secVec[0] = allPrvVec[0]; + secVec[1] = allPrvVec[1]; + secVec[2] = allPrvVec[0]; // same of secVec[0] + idVec[0] = allIdVec[0]; + idVec[1] = allIdVec[1]; + idVec[2] = allIdVec[0]; + bls::SecretKey sec; + CYBOZU_TEST_EXCEPTION_MESSAGE(sec.recover(secVec, idVec), std::exception, "same id"); + } + { + /* + n-out-of-n + can recover + */ + bls::SecretKey sec; + sec.recover(allPrvVec, allIdVec); + CYBOZU_TEST_EQUAL(sec, sec0); + } + /* + 2-out-of-n + can't recover + */ + secVec.resize(2); + idVec.resize(2); + for (int a = 0; a < n; a++) { + secVec[0] = allPrvVec[a]; + idVec[0] = allIdVec[a]; + for (int b = a + 1; b < n; b++) { + secVec[1] = allPrvVec[b]; + idVec[1] = allIdVec[b]; + bls::SecretKey sec; + sec.recover(secVec, idVec); + CYBOZU_TEST_ASSERT(sec != sec0); + } + } + /* + 3-out-of-n + can recover + */ + bls::SignatureVec sigVec(3); + idVec.resize(3); + for (int a = 0; a < n; a++) { + sigVec[0] = allSigVec[a]; + idVec[0] = allIdVec[a]; + for (int b = a + 1; b < n; b++) { + sigVec[1] = allSigVec[b]; + idVec[1] = allIdVec[b]; + for (int c = b + 1; c < n; c++) { + sigVec[2] = allSigVec[c]; + idVec[2] = allIdVec[c]; + bls::Signature sig; + sig.recover(sigVec, idVec); + CYBOZU_TEST_EQUAL(sig, sig0); + } + } + } + { + sigVec[0] = allSigVec[1]; idVec[0] = allIdVec[1]; + sigVec[1] = allSigVec[4]; idVec[1] = allIdVec[4]; + sigVec[2] = allSigVec[3]; idVec[2] = allIdVec[3]; + bls::Signature sig; + CYBOZU_BENCH_C("sig.recover", 100, sig.recover, sigVec, idVec); + } + { + /* + n-out-of-n + can recover + */ + bls::Signature sig; + sig.recover(allSigVec, allIdVec); + CYBOZU_TEST_EQUAL(sig, sig0); + } + /* + 2-out-of-n + can't recover + */ + sigVec.resize(2); + idVec.resize(2); + for (int a = 0; a < n; a++) { + sigVec[0] = allSigVec[a]; + idVec[0] = allIdVec[a]; + for (int b = a + 1; b < n; b++) { + sigVec[1] = allSigVec[b]; + idVec[1] = allIdVec[b]; + bls::Signature sig; + sig.recover(sigVec, idVec); + CYBOZU_TEST_ASSERT(sig != sig0); + } + } + // return same value if n = 1 + sigVec.resize(1); + idVec.resize(1); + sigVec[0] = allSigVec[0]; + idVec[0] = allIdVec[0]; + { + bls::Signature sig; + sig.recover(sigVec, idVec); + CYBOZU_TEST_EQUAL(sig, sigVec[0]); + } + // share and recover publicKey + { + bls::PublicKeyVec pubVec(k); + idVec.resize(k); + // select [0, k) publicKey + for (int i = 0; i < k; i++) { + allPrvVec[i].getPublicKey(pubVec[i]); + idVec[i] = allIdVec[i]; + } + bls::PublicKey pub; + pub.recover(pubVec, idVec); + CYBOZU_TEST_EQUAL(pub, pub0); + bls::PublicKey pub2; + pub2.recover(pubVec.data(), idVec.data(), pubVec.size()); + CYBOZU_TEST_EQUAL(pub, pub2); + } +} + +void popTest() +{ + const size_t k = 3; + const size_t n = 6; + const std::string m = "pop test"; + bls::SecretKey sec0; + sec0.init(); + bls::PublicKey pub0; + sec0.getPublicKey(pub0); + bls::Signature sig0; + sec0.sign(sig0, m); + CYBOZU_TEST_ASSERT(sig0.verify(pub0, m)); + + bls::SecretKeyVec msk; + sec0.getMasterSecretKey(msk, k); + + bls::PublicKeyVec mpk; + bls::getMasterPublicKey(mpk, msk); + bls::SignatureVec popVec; + bls::getPopVec(popVec, msk); + + for (size_t i = 0; i < popVec.size(); i++) { + CYBOZU_TEST_ASSERT(popVec[i].verify(mpk[i])); + } + + const int idTbl[n] = { + 3, 5, 193, 22, 15 + }; + bls::SecretKeyVec secVec(n); + bls::PublicKeyVec pubVec(n); + bls::SignatureVec sVec(n); + for (size_t i = 0; i < n; i++) { + int id = idTbl[i]; + secVec[i].set(msk, id); + secVec[i].getPublicKey(pubVec[i]); + bls::PublicKey pub; + pub.set(mpk, id); + CYBOZU_TEST_EQUAL(pubVec[i], pub); + + bls::Signature pop; + secVec[i].getPop(pop); + CYBOZU_TEST_ASSERT(pop.verify(pubVec[i])); + + secVec[i].sign(sVec[i], m); + CYBOZU_TEST_ASSERT(sVec[i].verify(pubVec[i], m)); + } + secVec.resize(k); + sVec.resize(k); + bls::IdVec idVec(k); + for (size_t i = 0; i < k; i++) { + idVec[i] = idTbl[i]; + } + bls::SecretKey sec; + sec.recover(secVec, idVec); + CYBOZU_TEST_EQUAL(sec, sec0); + bls::Signature sig; + sig.recover(sVec, idVec); + CYBOZU_TEST_EQUAL(sig, sig0); + bls::Signature sig2; + sig2.recover(sVec.data(), idVec.data(), sVec.size()); + CYBOZU_TEST_EQUAL(sig, sig2); +} + +void addTest() +{ + bls::SecretKey sec1, sec2; + sec1.init(); + sec2.init(); + CYBOZU_TEST_ASSERT(sec1 != sec2); + + bls::PublicKey pub1, pub2; + sec1.getPublicKey(pub1); + sec2.getPublicKey(pub2); + + const std::string m = "doremi"; + bls::Signature sig1, sig2; + sec1.sign(sig1, m); + sec2.sign(sig2, m); + CYBOZU_TEST_ASSERT((sig1 + sig2).verify(pub1 + pub2, m)); +} + +void aggregateTest() +{ + const size_t n = 10; + bls::SecretKey secs[n]; + bls::PublicKey pubs[n], pub; + bls::Signature sigs[n], sig; + const std::string m = "abc"; + for (size_t i = 0; i < n; i++) { + secs[i].init(); + secs[i].getPublicKey(pubs[i]); + secs[i].sign(sigs[i], m); + } + pub = pubs[0]; + sig = sigs[0]; + for (size_t i = 1; i < n; i++) { + pub.add(pubs[i]); + sig.add(sigs[i]); + } + CYBOZU_TEST_ASSERT(sig.verify(pub, m)); +} + +void dataTest() +{ + const size_t FrSize = bls::getFrByteSize(); + const size_t FpSize = bls::getG1ByteSize(); + bls::SecretKey sec; + sec.init(); + std::string str; + sec.getStr(str, bls::IoFixedByteSeq); + { + CYBOZU_TEST_EQUAL(str.size(), FrSize); + bls::SecretKey sec2; + sec2.setStr(str, bls::IoFixedByteSeq); + CYBOZU_TEST_EQUAL(sec, sec2); + } + bls::PublicKey pub; + sec.getPublicKey(pub); + pub.getStr(str, bls::IoFixedByteSeq); + { +#ifdef BLS_SWAP_G + CYBOZU_TEST_EQUAL(str.size(), FpSize); +#else + CYBOZU_TEST_EQUAL(str.size(), FpSize * 2); +#endif + bls::PublicKey pub2; + pub2.setStr(str, bls::IoFixedByteSeq); + CYBOZU_TEST_EQUAL(pub, pub2); + } + std::string m = "abc"; + bls::Signature sign; + sec.sign(sign, m); + sign.getStr(str, bls::IoFixedByteSeq); + { +#ifdef BLS_SWAP_G + CYBOZU_TEST_EQUAL(str.size(), FpSize * 2); +#else + CYBOZU_TEST_EQUAL(str.size(), FpSize); +#endif + bls::Signature sign2; + sign2.setStr(str, bls::IoFixedByteSeq); + CYBOZU_TEST_EQUAL(sign, sign2); + } + bls::Id id; + const uint64_t v[] = { 1, 2, 3, 4, 5, 6, }; + id.set(v); + id.getStr(str, bls::IoFixedByteSeq); + { + CYBOZU_TEST_EQUAL(str.size(), FrSize); + bls::Id id2; + id2.setStr(str, bls::IoFixedByteSeq); + CYBOZU_TEST_EQUAL(id, id2); + } +} + +void verifyAggregateTest() +{ + const size_t n = 10; + bls::SecretKey secs[n]; + bls::PublicKey pubs[n]; + bls::Signature sigs[n], sig; + const size_t sizeofHash = 32; + struct Hash { char data[sizeofHash]; }; + std::vector<Hash> h(n); + for (size_t i = 0; i < n; i++) { + char msg[128]; + CYBOZU_SNPRINTF(msg, sizeof(msg), "abc-%d", (int)i); + const size_t msgSize = strlen(msg); + cybozu::Sha256().digest(h[i].data, sizeofHash, msg, msgSize); + secs[i].init(); + secs[i].getPublicKey(pubs[i]); + secs[i].signHash(sigs[i], h[i].data, sizeofHash); + } + sig = sigs[0]; + for (size_t i = 1; i < n; i++) { + sig.add(sigs[i]); + } + CYBOZU_TEST_ASSERT(sig.verifyAggregatedHashes(pubs, h.data(), sizeofHash, n)); + bls::Signature invalidSig = sigs[0] + sigs[1]; + CYBOZU_TEST_ASSERT(!invalidSig.verifyAggregatedHashes(pubs, h.data(), sizeofHash, n)); + h[0].data[0]++; + CYBOZU_TEST_ASSERT(!sig.verifyAggregatedHashes(pubs, h.data(), sizeofHash, n)); +} + +unsigned int writeSeq(void *self, void *buf, unsigned int bufSize) +{ + int& seq = *(int*)self; + char *p = (char *)buf; + for (unsigned int i = 0; i < bufSize; i++) { + p[i] = char(seq++); + } + return bufSize; +} + +void setRandFuncTest() +{ + blsSecretKey sec; + const int seqInit1 = 5; + int seq = seqInit1; + blsSetRandFunc(&seq, writeSeq); + blsSecretKeySetByCSPRNG(&sec); + unsigned char buf[128]; + size_t n = blsSecretKeySerialize(buf, sizeof(buf), &sec); + CYBOZU_TEST_ASSERT(n > 0); + for (size_t i = 0; i < n - 1; i++) { + // ommit buf[n - 1] because it may be masked + CYBOZU_TEST_EQUAL(buf[i], seqInit1 + i); + } + // use default CSPRNG + blsSetRandFunc(0, 0); + blsSecretKeySetByCSPRNG(&sec); + n = blsSecretKeySerialize(buf, sizeof(buf), &sec); + CYBOZU_TEST_ASSERT(n > 0); + printf("sec="); + for (size_t i = 0; i < n; i++) { + printf("%02x", buf[i]); + } + printf("\n"); +} + +void testAll() +{ + blsTest(); + k_of_nTest(); + popTest(); + addTest(); + dataTest(); + aggregateTest(); + verifyAggregateTest(); + setRandFuncTest(); +} +CYBOZU_TEST_AUTO(all) +{ + const struct { + int type; + const char *name; + } tbl[] = { + { MCL_BN254, "BN254" }, +#if MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 6 + { MCL_BN381_1, "BN381_1" }, +#endif +#if MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 4 + { MCL_BLS12_381, "BLS12_381" }, +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + printf("curve=%s\n", tbl[i].name); + int type = tbl[i].type; + bls::init(type); + if (type == MCL_BN254) { + testForBN254(); + } + testAll(); + hashTest(type); + } +} diff --git a/vendor/github.com/dexon-foundation/bls/test/proj/bls_test/bls_test.vcxproj b/vendor/github.com/dexon-foundation/bls/test/proj/bls_test/bls_test.vcxproj new file mode 100644 index 000000000..1755135fb --- /dev/null +++ b/vendor/github.com/dexon-foundation/bls/test/proj/bls_test/bls_test.vcxproj @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{51266DE6-B57B-4AE3-B85C-282F170E1728}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>fp_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)debug.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)release.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="$(SolutionDir)test\\bls_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto/dkg/constant.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto/dkg/constant.go index 3e7ef4574..37d873d6f 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto/dkg/constant.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto/dkg/constant.go @@ -22,5 +22,5 @@ import ( ) const ( - curve = bls.CurveFp382_2 + curve = bls.BLS12_381 ) diff --git a/vendor/github.com/dexon-foundation/mcl/.gitignore b/vendor/github.com/dexon-foundation/mcl/.gitignore new file mode 100644 index 000000000..f5edb3706 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/.gitignore @@ -0,0 +1,13 @@ +CVS +java/*_wrap.cxx +lib/*.so +lib/*.a +*.class +GPATH +GRTAGS +GTAGS +*.o +*.d +*.exe +*.swp +.cvsignore diff --git a/vendor/github.com/dexon-foundation/mcl/.travis.yml b/vendor/github.com/dexon-foundation/mcl/.travis.yml new file mode 100644 index 000000000..73a97e6aa --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/.travis.yml @@ -0,0 +1,17 @@ +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 + diff --git a/vendor/github.com/dexon-foundation/mcl/CMakeLists.txt b/vendor/github.com/dexon-foundation/mcl/CMakeLists.txt index 8ac418098..aaa0a8cf2 100644 --- a/vendor/github.com/dexon-foundation/mcl/CMakeLists.txt +++ b/vendor/github.com/dexon-foundation/mcl/CMakeLists.txt @@ -36,6 +36,10 @@ else() add_definitions(-DMCL_USE_LLVM=1) set(SRCS ${SRCS} src/asm/aarch64.s) set(CPU arch64) + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm") + add_definitions(-DMCL_USE_LLVM=1) + set(SRCS ${SRCS} src/asm/arm.s) + set(CPU arm) elseif(APPLE) add_definitions(-DMCL_USE_LLVM=1) set(SRCS ${SRCS} src/asm/x86-64mac.s src/asm/x86-64mac.bmi2.s) @@ -85,18 +89,20 @@ include_directories( ) add_library(mcl STATIC ${SRCS}) -if(NOT MSVC) add_library(mcl_dy SHARED ${SRCS}) -endif() +target_link_libraries(mcl_dy ${LIBS}) +set_target_properties(mcl_dy PROPERTIES OUTPUT_NAME mcl) +#set_target_properties(mcl_dy PROPERTIES OUTPUT_NAME mcl VERSION 1.0.0 SOVERSION 1) +# For semantics of ABI compatibility including when you must bump SOVERSION, see: +# https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B#The_Do.27s_and_Don.27ts -file(GLOB MCL_HEADERS include/mcl/*.hpp include/mcl/*.h) +file(GLOB MCL_HEADERS include/mcl/*.hpp include/mcl/bn.h include/mcl/curve_type.h) file(GLOB CYBOZULIB_HEADERS include/cybozu/*.hpp) install(TARGETS mcl DESTINATION lib) -if(NOT MSVC) install(TARGETS mcl_dy DESTINATION lib) -endif() install(FILES ${MCL_HEADERS} DESTINATION include/mcl) +install(FILES include/mcl/impl/bn_c_impl.hpp DESTINATION include/mcl/impl) install(FILES ${CYBOZULIB_HEADERS} DESTINATION include/cybozu) set(TEST_BASE fp_test ec_test fp_util_test window_method_test elgamal_test fp_tower_test gmp_test bn_test glv_test) diff --git a/vendor/github.com/dexon-foundation/mcl/Makefile b/vendor/github.com/dexon-foundation/mcl/Makefile index fae248aba..7df1dd300 100644 --- a/vendor/github.com/dexon-foundation/mcl/Makefile +++ b/vendor/github.com/dexon-foundation/mcl/Makefile @@ -8,6 +8,7 @@ TEST_SRC+=bn_c256_test.cpp bn_c384_test.cpp bn_c384_256_test.cpp bn_c512_test.cp TEST_SRC+=aggregate_sig_test.cpp array_test.cpp TEST_SRC+=bls12_test.cpp TEST_SRC+=ecdsa_c_test.cpp +TEST_SRC+=modp_test.cpp ifeq ($(CPU),x86-64) MCL_USE_XBYAK?=1 TEST_SRC+=mont_fp_test.cpp sq_test.cpp @@ -26,15 +27,14 @@ endif ifeq ($(MCL_USE_XBYAK),0) CFLAGS+=-DMCL_DONT_USE_XBYAK endif -SHARE_BASENAME_SUF?=_dy ################################################################## MCL_LIB=$(LIB_DIR)/libmcl.a -MCL_SNAME=mcl$(SHARE_BASENAME_SUF) -BN256_SNAME=mclbn256$(SHARE_BASENAME_SUF) -BN384_SNAME=mclbn384$(SHARE_BASENAME_SUF) -BN384_256_SNAME=mclbn384_256$(SHARE_BASENAME_SUF) -BN512_SNAME=mclbn512$(SHARE_BASENAME_SUF) -SHE256_SNAME=mclshe256$(SHARE_BASENAME_SUF) +MCL_SNAME=mcl +BN256_SNAME=mclbn256 +BN384_SNAME=mclbn384 +BN384_256_SNAME=mclbn384_256 +BN512_SNAME=mclbn512 +SHE256_SNAME=mclshe256 MCL_SLIB=$(LIB_DIR)/lib$(MCL_SNAME).$(LIB_SUF) BN256_LIB=$(LIB_DIR)/libmclbn256.a BN256_SLIB=$(LIB_DIR)/lib$(BN256_SNAME).$(LIB_SUF) @@ -45,9 +45,10 @@ BN384_256_SLIB=$(LIB_DIR)/lib$(BN384_256_SNAME).$(LIB_SUF) BN512_LIB=$(LIB_DIR)/libmclbn512.a BN512_SLIB=$(LIB_DIR)/lib$(BN512_SNAME).$(LIB_SUF) SHE256_LIB=$(LIB_DIR)/libmclshe256.a +SHE256_SLIB=$(LIB_DIR)/lib$(SHE256_SNAME).$(LIB_SUF) SHE384_LIB=$(LIB_DIR)/libmclshe384.a ECDSA_LIB=$(LIB_DIR)/libmclecdsa.a -all: $(MCL_LIB) $(MCL_SLIB) $(BN256_LIB) $(BN256_SLIB) $(BN384_LIB) $(BN384_SLIB) $(BN384_256_LIB) $(BN384_256_SLIB) $(BN512_LIB) $(BN512_SLIB) $(SHE256_LIB) $(SHE384_lib) $(ECDSA_LIB) +all: $(MCL_LIB) $(MCL_SLIB) $(BN256_LIB) $(BN256_SLIB) $(BN384_LIB) $(BN384_SLIB) $(BN384_256_LIB) $(BN384_256_SLIB) $(BN512_LIB) $(BN512_SLIB) $(SHE256_LIB) $(SHE256_SLIB) $(SHE384_lib) $(ECDSA_LIB) #LLVM_VER=-3.8 LLVM_LLC=llc$(LLVM_VER) @@ -121,6 +122,7 @@ ifneq ($(findstring $(OS),mac/mingw64),) BN384_SLIB_LDFLAGS+=-l$(MCL_SNAME) -L./lib BN384_256_SLIB_LDFLAGS+=-l$(MCL_SNAME) -L./lib BN512_SLIB_LDFLAGS+=-l$(MCL_SNAME) -L./lib + SHE256_SLIB_LDFLAGS+=-l$(MCL_SNAME) -L./lib endif ifeq ($(OS),mingw64) MCL_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(MCL_SNAME).a @@ -128,6 +130,7 @@ ifeq ($(OS),mingw64) BN384_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(BN384_SNAME).a BN384_256_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(BN384_256_SNAME).a BN512_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(BN512_SNAME).a + SHE256_SLIB_LDFLAGS+=-Wl,--out-implib,$(LIB_DIR)/lib$(SHE256_SNAME).a endif $(MCL_LIB): $(LIB_OBJ) @@ -142,6 +145,9 @@ $(BN256_LIB): $(BN256_OBJ) $(SHE256_LIB): $(SHE256_OBJ) $(AR) $@ $(SHE256_OBJ) +$(SHE256_SLIB): $(SHE256_OBJ) $(MCL_LIB) + $(PRE)$(CXX) -o $@ $(SHE256_OBJ) $(MCL_LIB) -shared $(LDFLAGS) $(SHE256_SLIB_LDFLAGS) + $(SHE384_LIB): $(SHE384_OBJ) $(AR) $@ $(SHE384_OBJ) @@ -199,7 +205,7 @@ else endif $(GEN_EXE): src/gen.cpp src/llvm_gen.hpp - $(CXX) -o $@ $< $(CFLAGS) -O0 + $(CXX) -o $@ $< $(CFLAGS) asm: $(LLVM_SRC) $(LLVM_OPT) -O3 -o - $(LLVM_SRC) | $(LLVM_LLC) -O3 $(LLVM_FLAGS) -x86-asm-syntax=intel @@ -207,21 +213,27 @@ asm: $(LLVM_SRC) $(LOW_ASM_OBJ): $(LOW_ASM_SRC) $(ASM) $< -ifeq ($(OS),mac) - MAC_GO_LDFLAGS="-ldflags=-s" -endif -# set PATH for mingw, set LD_RUN_PATH is for other env +# set PATH for mingw, set LD_LIBRARY_PATH is for other env +COMMON_LIB_PATH="../../../lib" +PATH_VAL=$$PATH:$(COMMON_LIB_PATH) LD_LIBRARY_PATH=$(COMMON_LIB_PATH) DYLD_LIBRARY_PATH=$(COMMON_LIB_PATH) CGO_CFLAGS="-I$(shell pwd)/include" CGO_LDFLAGS="-L../../../lib" test_go256: $(MCL_SLIB) $(BN256_SLIB) -# cd ffi/go/mcl && env PATH="$$PATH:../../../lib" LD_RUN_PATH="../../../lib" CGO_LDFLAGS="-L../../../lib -l$(BN256_SNAME) -l$(MCL_SNAME) -lgmpxx -lgmp -lcrypto -lstdc++" go test $(MAC_GO_LDFLAGS) -tags bn256 . - cd ffi/go/mcl && env PATH="$$PATH:../../../lib" LD_RUN_PATH="../../../lib" go test $(MAC_GO_LDFLAGS) -tags bn256 . + cd ffi/go/mcl && env PATH=$(PATH_VAL) go test -tags bn256 . test_go384: $(MCL_SLIB) $(BN384_SLIB) -# cd ffi/go/mcl && env LD_RUN_PATH="../../../lib" CGO_CFLAGS="-I../../../include" CGO_LDFLAGS="-L../../../lib -l$(BN384_SNAME) -l$(MCL_SNAME) -lgmpxx -lgmp -lcrypto -lstdc++" go test $(MAC_GO_LDFLAGS) . - cd ffi/go/mcl && env PATH="$$PATH:../../../lib" LD_RUN_PATH="../../../lib" go test $(MAC_GO_LDFLAGS) -tags bn384 . + cd ffi/go/mcl && env PATH=$(PATH_VAL) go test -tags bn384 . + +test_go384_256: $(MCL_SLIB) $(BN384_256_SLIB) + cd ffi/go/mcl && env PATH=$(PATH_VAL) go test -tags bn384_256 . test_go: $(MAKE) test_go256 $(MAKE) test_go384 + $(MAKE) test_go384_256 + +test_python_she: $(SHE256_SLIB) + cd ffi/python && env LD_LIBRARY_PATH="../../lib" DYLD_LIBRARY_PATH="../../lib" PATH=$$PATH:"../../lib" python3 she.py +test_python: + $(MAKE) test_python_she test_java: $(MAKE) -C ffi/java test @@ -265,10 +277,18 @@ $(EXE_DIR)/she_c384_test.exe: $(OBJ_DIR)/she_c384_test.o $(SHE384_LIB) $(MCL_LIB $(EXE_DIR)/ecdsa_c_test.exe: $(OBJ_DIR)/ecdsa_c_test.o $(ECDSA_LIB) $(MCL_LIB) src/ecdsa_c.cpp include/mcl/ecdsa.hpp include/mcl/ecdsa.h $(PRE)$(CXX) $< -o $@ $(ECDSA_LIB) $(MCL_LIB) $(LDFLAGS) +$(OBJ_DIR)/modp_test.o: test/modp_test.cpp + $(PRE)$(CXX) -c $< -o $@ -MMD -MP -MF $(@:.o=.d) -DMCL_USE_VINT -DMCL_MAX_BIT_SIZE=384 -DMCL_VINT_64BIT_PORTABLE -DMCL_SIZEOF_UNIT=8 -DMCL_VINT_FIXED_BUFFER -I./include -O2 $(CFLAGS_WARN) + +$(EXE_DIR)/modp_test.exe: $(OBJ_DIR)/modp_test.o + $(PRE)$(CXX) $< -o $@ + SAMPLE_EXE=$(addprefix $(EXE_DIR)/,$(addsuffix .exe,$(basename $(SAMPLE_SRC)))) sample: $(SAMPLE_EXE) $(MCL_LIB) TEST_EXE=$(addprefix $(EXE_DIR)/,$(TEST_SRC:.cpp=.exe)) +test_ci: $(TEST_EXE) + @sh -ec 'for i in $(TEST_EXE); do echo $$i; env LSAN_OPTIONS=verbosity=1:log_threads=1 $$i; done' test: $(TEST_EXE) @echo test $(TEST_EXE) @sh -ec 'for i in $(TEST_EXE); do $$i|grep "ctest:name"; done' > result.txt @@ -279,8 +299,8 @@ EMCC_OPT+=-O3 -DNDEBUG -DMCLSHE_WIN_SIZE=8 EMCC_OPT+=-s WASM=1 -s NO_EXIT_RUNTIME=1 -s MODULARIZE=1 #-s ASSERTIONS=1 EMCC_OPT+=-DCYBOZU_MINIMUM_EXCEPTION EMCC_OPT+=-s ABORTING_MALLOC=0 -SHE_C_DEP=src/fp.cpp src/she_c_impl.hpp include/mcl/she.hpp include/mcl/she.h Makefile -MCL_C_DEP=src/fp.cpp src/bn_c_impl.hpp include/mcl/bn.hpp include/mcl/bn.h Makefile +SHE_C_DEP=src/fp.cpp src/she_c_impl.hpp include/mcl/she.hpp include/mcl/fp.hpp include/mcl/op.hpp include/mcl/she.h Makefile +MCL_C_DEP=src/fp.cpp include/mcl/impl/bn_c_impl.hpp include/mcl/bn.hpp include/mcl/fp.hpp include/mcl/op.hpp include/mcl/bn.h Makefile ifeq ($(MCL_USE_LLVM),2) EMCC_OPT+=src/base64m.ll -DMCL_USE_LLVM SHE_C_DEP+=src/base64m.ll @@ -328,21 +348,23 @@ make_tbl: update_xbyak: cp -a ../xbyak/xbyak/xbyak.h ../xbyak/xbyak/xbyak_util.h ../xbyak/xbyak/xbyak_mnemonic.h src/xbyak/ +update_cybozulib: + cp -a $(addprefix ../cybozulib/,$(wildcard include/cybozu/*.hpp)) include/cybozu/ clean: - $(RM) $(LIB_DIR)/*.a $(EXE_DIR)/*.$(LIB_SUF) $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d $(EXE_DIR)/*.exe $(GEN_EXE) $(ASM_OBJ) $(LIB_OBJ) $(BN256_OBJ) $(BN384_OBJ) $(BN512_OBJ) $(LLVM_SRC) $(FUNC_LIST) src/*.ll lib/*.a + $(RM) $(LIB_DIR)/*.a $(LIB_DIR)/*.$(LIB_SUF) $(OBJ_DIR)/*.o $(OBJ_DIR)/*.obj $(OBJ_DIR)/*.d $(EXE_DIR)/*.exe $(GEN_EXE) $(ASM_OBJ) $(LIB_OBJ) $(BN256_OBJ) $(BN384_OBJ) $(BN512_OBJ) $(LLVM_SRC) $(FUNC_LIST) src/*.ll lib/*.a ALL_SRC=$(SRC_SRC) $(TEST_SRC) $(SAMPLE_SRC) DEPEND_FILE=$(addprefix $(OBJ_DIR)/, $(addsuffix .d,$(basename $(ALL_SRC)))) -include $(DEPEND_FILE) PREFIX?=/usr/local -install: lib/libmcl.a lib/libmcl$(SHARE_BASENAME_SUF).$(LIB_SUF) +install: lib/libmcl.a lib/libmcl.$(LIB_SUF) $(MKDIR) $(PREFIX)/include/mcl cp -a include/mcl/ $(PREFIX)/include/ cp -a include/cybozu/ $(PREFIX)/include/ $(MKDIR) $(PREFIX)/lib - cp -a lib/libmcl.a lib/libmcl$(SHARE_BASENAME_SUF).$(LIB_SUF) $(PREFIX)/lib/ + cp -a lib/libmcl.a lib/libmcl.$(LIB_SUF) $(PREFIX)/lib/ .PHONY: test mcl-wasm she-wasm bin/emu diff --git a/vendor/github.com/dexon-foundation/mcl/common.mk b/vendor/github.com/dexon-foundation/mcl/common.mk index a05f5c9cb..5c749e1a6 100644 --- a/vendor/github.com/dexon-foundation/mcl/common.mk +++ b/vendor/github.com/dexon-foundation/mcl/common.mk @@ -78,7 +78,7 @@ else endif ifeq ($(MARCH),) ifeq ($(INTEL),1) - CFLAGS_OPT+=-march=native +# CFLAGS_OPT+=-march=native endif else CFLAGS_OPT+=$(MARCH) diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/cs/App.config b/vendor/github.com/dexon-foundation/mcl/ffi/cs/App.config new file mode 100644 index 000000000..88fa4027b --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/cs/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> + </startup> +</configuration>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/cs/Properties/AssemblyInfo.cs b/vendor/github.com/dexon-foundation/mcl/ffi/cs/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..c87e1d44b --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/cs/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリã«é–¢ã™ã‚‹ä¸€èˆ¬æƒ…å ±ã¯ä»¥ä¸‹ã®å±žæ€§ã‚»ãƒƒãƒˆã‚’ã¨ãŠã—ã¦åˆ¶å¾¡ã•ã‚Œã¾ã™ã€‚ +// アセンブリã«é–¢é€£ä»˜ã‘られã¦ã„ã‚‹æƒ…å ±ã‚’å¤‰æ›´ã™ã‚‹ã«ã¯ã€ +// ã“れらã®å±žæ€§å€¤ã‚’変更ã—ã¦ãã ã•ã„。 +[assembly: AssemblyTitle("bn256")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("bn256")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible ã‚’ false ã«è¨å®šã™ã‚‹ã¨ã€ãã®åž‹ã¯ã“ã®ã‚¢ã‚»ãƒ³ãƒ–リ内㧠COM コンãƒãƒ¼ãƒãƒ³ãƒˆã‹ã‚‰ +// å‚ç…§ä¸å¯èƒ½ã«ãªã‚Šã¾ã™ã€‚COM ã‹ã‚‰ã“ã®ã‚¢ã‚»ãƒ³ãƒ–リ内ã®åž‹ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ã€ +// ãã®åž‹ã® ComVisible 属性を true ã«è¨å®šã—ã¦ãã ã•ã„。 +[assembly: ComVisible(false)] + +// ã“ã®ãƒ—ãƒã‚¸ã‚§ã‚¯ãƒˆãŒ COM ã«å…¬é–‹ã•ã‚Œã‚‹å ´åˆã€æ¬¡ã® GUID ㌠typelib ã® ID ã«ãªã‚Šã¾ã™ +[assembly: Guid("e9d06b1b-ea22-4ef4-ba4b-422f7625966b")] + +// アセンブリã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±ã¯æ¬¡ã® 4 ã¤ã®å€¤ã§æ§‹æˆã•ã‚Œã¦ã„ã¾ã™: +// +// メジャー ãƒãƒ¼ã‚¸ãƒ§ãƒ³ +// マイナー ãƒãƒ¼ã‚¸ãƒ§ãƒ³ +// ãƒ“ãƒ«ãƒ‰ç•ªå· +// Revision +// +// ã™ã¹ã¦ã®å€¤ã‚’指定ã™ã‚‹ã‹ã€ä¸‹ã®ã‚ˆã†ã« '*' を使ã£ã¦ãƒ“ルドãŠã‚ˆã³ãƒªãƒ“ジョン番å·ã‚’ +// 既定値ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.cs b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.cs new file mode 100644 index 000000000..0e1ed032c --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.cs @@ -0,0 +1,475 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace mcl { + public class BN256 { + [DllImport("mclBn256.dll")] + public static extern int mclBn_init(int curve, int maxUnitSize); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_clear(ref Fr x); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_setInt(ref Fr y, int x); + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_setStr(ref Fr x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_isValid(ref Fr x); + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_isEqual(ref Fr x, ref Fr y); + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_isZero(ref Fr x); + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_isOne(ref Fr x); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_setByCSPRNG(ref Fr x); + + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_setHashOf(ref Fr x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); + [DllImport("mclBn256.dll")] + public static extern int mclBnFr_getStr([Out]StringBuilder buf, long maxBufSize, ref Fr x, int ioMode); + + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_neg(ref Fr y, ref Fr x); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_inv(ref Fr y, ref Fr x); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_add(ref Fr z, ref Fr x, ref Fr y); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_sub(ref Fr z, ref Fr x, ref Fr y); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_mul(ref Fr z, ref Fr x, ref Fr y); + [DllImport("mclBn256.dll")] + public static extern void mclBnFr_div(ref Fr z, ref Fr x, ref Fr y); + + [DllImport("mclBn256.dll")] + public static extern void mclBnG1_clear(ref G1 x); + [DllImport("mclBn256.dll")] + public static extern int mclBnG1_setStr(ref G1 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); + [DllImport("mclBn256.dll")] + public static extern int mclBnG1_isValid(ref G1 x); + [DllImport("mclBn256.dll")] + public static extern int mclBnG1_isEqual(ref G1 x, ref G1 y); + [DllImport("mclBn256.dll")] + public static extern int mclBnG1_isZero(ref G1 x); + [DllImport("mclBn256.dll")] + public static extern int mclBnG1_hashAndMapTo(ref G1 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); + [DllImport("mclBn256.dll")] + public static extern long mclBnG1_getStr([Out]StringBuilder buf, long maxBufSize, ref G1 x, int ioMode); + [DllImport("mclBn256.dll")] + public static extern void mclBnG1_neg(ref G1 y, ref G1 x); + [DllImport("mclBn256.dll")] + public static extern void mclBnG1_dbl(ref G1 y, ref G1 x); + [DllImport("mclBn256.dll")] + public static extern void mclBnG1_add(ref G1 z, ref G1 x, ref G1 y); + [DllImport("mclBn256.dll")] + public static extern void mclBnG1_sub(ref G1 z, ref G1 x, ref G1 y); + [DllImport("mclBn256.dll")] + public static extern void mclBnG1_mul(ref G1 z, ref G1 x, ref Fr y); + + [DllImport("mclBn256.dll")] + public static extern void mclBnG2_clear(ref G2 x); + [DllImport("mclBn256.dll")] + public static extern int mclBnG2_setStr(ref G2 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); + [DllImport("mclBn256.dll")] + public static extern int mclBnG2_isValid(ref G2 x); + [DllImport("mclBn256.dll")] + public static extern int mclBnG2_isEqual(ref G2 x, ref G2 y); + [DllImport("mclBn256.dll")] + public static extern int mclBnG2_isZero(ref G2 x); + [DllImport("mclBn256.dll")] + public static extern int mclBnG2_hashAndMapTo(ref G2 x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize); + [DllImport("mclBn256.dll")] + public static extern long mclBnG2_getStr([Out]StringBuilder buf, long maxBufSize, ref G2 x, int ioMode); + [DllImport("mclBn256.dll")] + public static extern void mclBnG2_neg(ref G2 y, ref G2 x); + [DllImport("mclBn256.dll")] + public static extern void mclBnG2_dbl(ref G2 y, ref G2 x); + [DllImport("mclBn256.dll")] + public static extern void mclBnG2_add(ref G2 z, ref G2 x, ref G2 y); + [DllImport("mclBn256.dll")] + public static extern void mclBnG2_sub(ref G2 z, ref G2 x, ref G2 y); + [DllImport("mclBn256.dll")] + public static extern void mclBnG2_mul(ref G2 z, ref G2 x, ref Fr y); + + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_clear(ref GT x); + [DllImport("mclBn256.dll")] + public static extern int mclBnGT_setStr(ref GT x, [In][MarshalAs(UnmanagedType.LPStr)] string buf, long bufSize, int ioMode); + [DllImport("mclBn256.dll")] + public static extern int mclBnGT_isEqual(ref GT x, ref GT y); + [DllImport("mclBn256.dll")] + public static extern int mclBnGT_isZero(ref GT x); + [DllImport("mclBn256.dll")] + public static extern int mclBnGT_isOne(ref GT x); + [DllImport("mclBn256.dll")] + public static extern long mclBnGT_getStr([Out]StringBuilder buf, long maxBufSize, ref GT x, int ioMode); + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_neg(ref GT y, ref GT x); + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_inv(ref GT y, ref GT x); + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_add(ref GT z, ref GT x, ref GT y); + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_sub(ref GT z, ref GT x, ref GT y); + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_mul(ref GT z, ref GT x, ref GT y); + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_div(ref GT z, ref GT x, ref GT y); + + [DllImport("mclBn256.dll")] + public static extern void mclBnGT_pow(ref GT z, ref GT x, ref Fr y); + [DllImport("mclBn256.dll")] + public static extern void mclBn_pairing(ref GT z, ref G1 x, ref G2 y); + [DllImport("mclBn256.dll")] + public static extern void mclBn_finalExp(ref GT y, ref GT x); + [DllImport("mclBn256.dll")] + public static extern void mclBn_millerLoop(ref GT z, ref G1 x, ref G2 y); + + public static void init() + { + const int curveFp254BNb = 0; + const int maxUnitSize = 4; + if (mclBn_init(curveFp254BNb, maxUnitSize) != 0) { + throw new InvalidOperationException("mclBn_init"); + } + } + [StructLayout(LayoutKind.Sequential)] + public struct Fr { + private ulong v0, v1, v2, v3; + public void Clear() + { + mclBnFr_clear(ref this); + } + public void SetInt(int x) + { + mclBnFr_setInt(ref this, x); + } + public void SetStr(string s, int ioMode) + { + if (mclBnFr_setStr(ref this, s, s.Length, ioMode) != 0) { + throw new ArgumentException("mclBnFr_setStr" + s); + } + } + public bool IsValid() + { + return mclBnFr_isValid(ref this) == 1; + } + public bool Equals(Fr rhs) + { + return mclBnFr_isEqual(ref this, ref rhs) == 1; + } + public bool IsZero() + { + return mclBnFr_isZero(ref this) == 1; + } + public bool IsOne() + { + return mclBnFr_isOne(ref this) == 1; + } + public void SetByCSPRNG() + { + mclBnFr_setByCSPRNG(ref this); + } + public void SetHashOf(String s) + { + if (mclBnFr_setHashOf(ref this, s, s.Length) != 0) { + throw new InvalidOperationException("mclBnFr_setHashOf:" + s); + } + } + public string GetStr(int ioMode) + { + StringBuilder sb = new StringBuilder(1024); + long size = mclBnFr_getStr(sb, sb.Capacity, ref this, ioMode); + if (size == 0) { + throw new InvalidOperationException("mclBnFr_getStr:"); + } + return sb.ToString(); + } + public void Neg(Fr x) + { + mclBnFr_neg(ref this, ref x); + } + public void Inv(Fr x) + { + mclBnFr_inv(ref this, ref x); + } + public void Add(Fr x, Fr y) + { + mclBnFr_add(ref this, ref x, ref y); + } + public void Sub(Fr x, Fr y) + { + mclBnFr_sub(ref this, ref x, ref y); + } + public void Mul(Fr x, Fr y) + { + mclBnFr_mul(ref this, ref x, ref y); + } + public void Div(Fr x, Fr y) + { + mclBnFr_div(ref this, ref x, ref y); + } + public static Fr operator -(Fr x) + { + Fr y = new Fr(); + y.Neg(x); + return y; + } + public static Fr operator +(Fr x, Fr y) + { + Fr z = new Fr(); + z.Add(x, y); + return z; + } + public static Fr operator -(Fr x, Fr y) + { + Fr z = new Fr(); + z.Sub(x, y); + return z; + } + public static Fr operator *(Fr x, Fr y) + { + Fr z = new Fr(); + z.Mul(x, y); + return z; + } + public static Fr operator /(Fr x, Fr y) + { + Fr z = new Fr(); + z.Div(x, y); + return z; + } + } + [StructLayout(LayoutKind.Sequential)] + public struct G1 { + private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11; + public void Clear() + { + mclBnG1_clear(ref this); + } + public void setStr(String s, int ioMode) + { + if (mclBnG1_setStr(ref this, s, s.Length, ioMode) != 0) { + throw new ArgumentException("mclBnG1_setStr:" + s); + } + } + public bool IsValid() + { + return mclBnG1_isValid(ref this) == 1; + } + public bool Equals(G1 rhs) + { + return mclBnG1_isEqual(ref this, ref rhs) == 1; + } + public bool IsZero() + { + return mclBnG1_isZero(ref this) == 1; + } + public void HashAndMapTo(String s) + { + if (mclBnG1_hashAndMapTo(ref this, s, s.Length) != 0) { + throw new ArgumentException("mclBnG1_hashAndMapTo:" + s); + } + } + public string GetStr(int ioMode) + { + StringBuilder sb = new StringBuilder(1024); + long size = mclBnG1_getStr(sb, sb.Capacity, ref this, ioMode); + if (size == 0) { + throw new InvalidOperationException("mclBnG1_getStr:"); + } + return sb.ToString(); + } + public void Neg(G1 x) + { + mclBnG1_neg(ref this, ref x); + } + public void Dbl(G1 x) + { + mclBnG1_dbl(ref this, ref x); + } + public void Add(G1 x, G1 y) + { + mclBnG1_add(ref this, ref x, ref y); + } + public void Sub(G1 x, G1 y) + { + mclBnG1_sub(ref this, ref x, ref y); + } + public void Mul(G1 x, Fr y) + { + mclBnG1_mul(ref this, ref x, ref y); + } + } + [StructLayout(LayoutKind.Sequential)] + public struct G2 { + private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11; + private ulong v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23; + public void Clear() + { + mclBnG2_clear(ref this); + } + public void setStr(String s, int ioMode) + { + if (mclBnG2_setStr(ref this, s, s.Length, ioMode) != 0) { + throw new ArgumentException("mclBnG2_setStr:" + s); + } + } + public bool IsValid() + { + return mclBnG2_isValid(ref this) == 1; + } + public bool Equals(G2 rhs) + { + return mclBnG2_isEqual(ref this, ref rhs) == 1; + } + public bool IsZero() + { + return mclBnG2_isZero(ref this) == 1; + } + public void HashAndMapTo(String s) + { + if (mclBnG2_hashAndMapTo(ref this, s, s.Length) != 0) { + throw new ArgumentException("mclBnG2_hashAndMapTo:" + s); + } + } + public string GetStr(int ioMode) + { + StringBuilder sb = new StringBuilder(1024); + long size = mclBnG2_getStr(sb, sb.Capacity, ref this, ioMode); + if (size == 0) { + throw new InvalidOperationException("mclBnG2_getStr:"); + } + return sb.ToString(); + } + public void Neg(G2 x) + { + mclBnG2_neg(ref this, ref x); + } + public void Dbl(G2 x) + { + mclBnG2_dbl(ref this, ref x); + } + public void Add(G2 x, G2 y) + { + mclBnG2_add(ref this, ref x, ref y); + } + public void Sub(G2 x, G2 y) + { + mclBnG2_sub(ref this, ref x, ref y); + } + public void Mul(G2 x, Fr y) + { + mclBnG2_mul(ref this, ref x, ref y); + } + } + [StructLayout(LayoutKind.Sequential)] + public struct GT { + private ulong v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11; + private ulong v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23; + private ulong v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35; + private ulong v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47; + public void Clear() + { + mclBnGT_clear(ref this); + } + public void setStr(String s, int ioMode) + { + if (mclBnGT_setStr(ref this, s, s.Length, ioMode) != 0) { + throw new ArgumentException("mclBnGT_setStr:" + s); + } + } + public bool Equals(GT rhs) + { + return mclBnGT_isEqual(ref this, ref rhs) == 1; + } + public bool IsZero() + { + return mclBnGT_isZero(ref this) == 1; + } + public bool IsOne() + { + return mclBnGT_isOne(ref this) == 1; + } + public string GetStr(int ioMode) + { + StringBuilder sb = new StringBuilder(1024); + long size = mclBnGT_getStr(sb, sb.Capacity, ref this, ioMode); + if (size == 0) { + throw new InvalidOperationException("mclBnGT_getStr:"); + } + return sb.ToString(); + } + public void Neg(GT x) + { + mclBnGT_neg(ref this, ref x); + } + public void Inv(GT x) + { + mclBnGT_inv(ref this, ref x); + } + public void Add(GT x, GT y) + { + mclBnGT_add(ref this, ref x, ref y); + } + public void Sub(GT x, GT y) + { + mclBnGT_sub(ref this, ref x, ref y); + } + public void Mul(GT x, GT y) + { + mclBnGT_mul(ref this, ref x, ref y); + } + public void Div(GT x, GT y) + { + mclBnGT_div(ref this, ref x, ref y); + } + public static GT operator -(GT x) + { + GT y = new GT(); + y.Neg(x); + return y; + } + public static GT operator +(GT x, GT y) + { + GT z = new GT(); + z.Add(x, y); + return z; + } + public static GT operator -(GT x, GT y) + { + GT z = new GT(); + z.Sub(x, y); + return z; + } + public static GT operator *(GT x, GT y) + { + GT z = new GT(); + z.Mul(x, y); + return z; + } + public static GT operator /(GT x, GT y) + { + GT z = new GT(); + z.Div(x, y); + return z; + } + public void Pow(GT x, Fr y) + { + mclBnGT_pow(ref this, ref x, ref y); + } + public void Pairing(G1 x, G2 y) + { + mclBn_pairing(ref this, ref x, ref y); + } + public void FinalExp(GT x) + { + mclBn_finalExp(ref this, ref x); + } + public void MillerLoop(G1 x, G2 y) + { + mclBn_millerLoop(ref this, ref x, ref y); + } + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.csproj b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.csproj new file mode 100644 index 000000000..21a049f01 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.csproj @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{E9D06B1B-EA22-4EF4-BA4B-422F7625966B}</ProjectGuid> + <OutputType>Exe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>bn256</RootNamespace> + <AssemblyName>bn256</AssemblyName> + <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + <DebugSymbols>true</DebugSymbols> + <OutputPath>..\..\bin\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <AllowUnsafeBlocks>false</AllowUnsafeBlocks> + <DebugType>full</DebugType> + <PlatformTarget>x64</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + <OutputPath>..\..\bin\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <Optimize>true</Optimize> + <DebugType>pdbonly</DebugType> + <PlatformTarget>x64</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> + <Prefer32Bit>true</Prefer32Bit> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Net.Http" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="bn256.cs" /> + <Compile Include="bn256_test.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="App.config" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.sln b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.sln new file mode 100644 index 000000000..6e6aa67ee --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bn256", "bn256.csproj", "{E9D06B1B-EA22-4EF4-BA4B-422F7625966B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E9D06B1B-EA22-4EF4-BA4B-422F7625966B}.Debug|x64.ActiveCfg = Debug|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966B}.Debug|x64.Build.0 = Debug|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966B}.Release|x64.ActiveCfg = Release|x64 + {E9D06B1B-EA22-4EF4-BA4B-422F7625966B}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256_test.cs b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256_test.cs new file mode 100644 index 000000000..cad8c03d3 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/cs/bn256_test.cs @@ -0,0 +1,149 @@ +using System; + +namespace mcl { + using static BN256; + class BN256Test { + static int err = 0; + static void assert(string msg, bool b) + { + if (b) return; + Console.WriteLine("ERR {0}", msg); + err++; + } + static void Main(string[] args) + { + try { + assert("64bit system", System.Environment.Is64BitProcess); + init(); + TestFr(); + TestG1(); + TestG2(); + TestPairing(); + if (err == 0) { + Console.WriteLine("all tests succeed"); + } else { + Console.WriteLine("err={0}", err); + } + } catch (Exception e) { + Console.WriteLine("ERR={0}", e); + } + } + static void TestFr() + { + Console.WriteLine("TestFr"); + Fr x = new Fr(); + 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)); + try { + x.SetStr("1234567891234x", 10); + Console.WriteLine("x = {0}", x); + } catch (Exception e) { + Console.WriteLine("exception test OK\n'{0}'", e); + } + x.SetStr("1234567891234", 10); + assert("1234567891234", x.GetStr(10) == "1234567891234"); + } + static void TestG1() + { + Console.WriteLine("TestG1"); + G1 P = new G1(); + 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)); + } + static void TestG2() + { + Console.WriteLine("TestG2"); + G2 P = new G2(); + 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)); + } + 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)); + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/go/mcl/mcl.go b/vendor/github.com/dexon-foundation/mcl/ffi/go/mcl/mcl.go new file mode 100644 index 000000000..a0c8bb4d3 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/go/mcl/mcl.go @@ -0,0 +1,659 @@ +package mcl + +/* +#cgo bn256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=4 +#cgo bn384 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 +#cgo bn384_256 CFLAGS:-DMCLBN_FP_UNIT_SIZE=6 -DMCLBN_FR_UNIT_SIZE=4 +#cgo bn256 LDFLAGS:-lmclbn256 -lmcl +#cgo bn384 LDFLAGS:-lmclbn384 -lmcl +#cgo bn384_256 LDFLAGS:-lmclbn384_256 -lmcl +#include <mcl/bn.h> +*/ +import "C" +import "fmt" +import "unsafe" + +// CurveFp254BNb -- 254 bit curve +const CurveFp254BNb = C.mclBn_CurveFp254BNb + +// CurveFp382_1 -- 382 bit curve 1 +const CurveFp382_1 = C.mclBn_CurveFp382_1 + +// CurveFp382_2 -- 382 bit curve 2 +const CurveFp382_2 = C.mclBn_CurveFp382_2 + +// BLS12_381 +const BLS12_381 = C.MCL_BLS12_381 + +// IoSerializeHexStr +const IoSerializeHexStr = C.MCLBN_IO_SERIALIZE_HEX_STR + +// Init -- +// call this function before calling all the other operations +// this function is not thread safe +func Init(curve int) error { + err := C.mclBn_init(C.int(curve), C.MCLBN_COMPILED_TIME_VAR) + if err != 0 { + return fmt.Errorf("ERR mclBn_init curve=%d", curve) + } + return nil +} + +// GetFrUnitSize() -- +func GetFrUnitSize() int { + return int(C.MCLBN_FR_UNIT_SIZE) +} + +// GetFpUnitSize() -- +// same as GetMaxOpUnitSize() +func GetFpUnitSize() int { + return int(C.MCLBN_FP_UNIT_SIZE) +} + +// GetMaxOpUnitSize -- +func GetMaxOpUnitSize() int { + return int(C.MCLBN_FP_UNIT_SIZE) +} + +// GetOpUnitSize -- +// the length of Fr is GetOpUnitSize() * 8 bytes +func GetOpUnitSize() int { + return int(C.mclBn_getOpUnitSize()) +} + +// GetCurveOrder -- +// return the order of G1 +func GetCurveOrder() string { + buf := make([]byte, 1024) + // #nosec + n := C.mclBn_getCurveOrder((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) + if n == 0 { + panic("implementation err. size of buf is small") + } + return string(buf[:n]) +} + +// GetFieldOrder -- +// return the characteristic of the field where a curve is defined +func GetFieldOrder() string { + buf := make([]byte, 1024) + // #nosec + n := C.mclBn_getFieldOrder((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) + if n == 0 { + panic("implementation err. size of buf is small") + } + return string(buf[:n]) +} + +// Fr -- +type Fr struct { + v C.mclBnFr +} + +// getPointer -- +func (x *Fr) getPointer() (p *C.mclBnFr) { + // #nosec + return (*C.mclBnFr)(unsafe.Pointer(x)) +} + +// Clear -- +func (x *Fr) Clear() { + // #nosec + C.mclBnFr_clear(x.getPointer()) +} + +// SetInt64 -- +func (x *Fr) SetInt64(v int64) { + // #nosec + C.mclBnFr_setInt(x.getPointer(), C.int64_t(v)) +} + +// SetString -- +func (x *Fr) SetString(s string, base int) error { + buf := []byte(s) + // #nosec + err := C.mclBnFr_setStr(x.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(base)) + if err != 0 { + return fmt.Errorf("err mclBnFr_setStr %x", err) + } + return nil +} + +// Deserialize -- +func (x *Fr) Deserialize(buf []byte) error { + // #nosec + err := C.mclBnFr_deserialize(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err == 0 { + return fmt.Errorf("err mclBnFr_deserialize %x", buf) + } + return nil +} + +// SetLittleEndian -- +func (x *Fr) SetLittleEndian(buf []byte) error { + // #nosec + err := C.mclBnFr_setLittleEndian(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err != 0 { + return fmt.Errorf("err mclBnFr_setLittleEndian %x", err) + } + return nil +} + +// IsEqual -- +func (x *Fr) IsEqual(rhs *Fr) bool { + return C.mclBnFr_isEqual(x.getPointer(), rhs.getPointer()) == 1 +} + +// IsZero -- +func (x *Fr) IsZero() bool { + return C.mclBnFr_isZero(x.getPointer()) == 1 +} + +// IsOne -- +func (x *Fr) IsOne() bool { + return C.mclBnFr_isOne(x.getPointer()) == 1 +} + +// SetByCSPRNG -- +func (x *Fr) SetByCSPRNG() { + err := C.mclBnFr_setByCSPRNG(x.getPointer()) + if err != 0 { + panic("err mclBnFr_setByCSPRNG") + } +} + +// SetHashOf -- +func (x *Fr) SetHashOf(buf []byte) bool { + // #nosec + return C.mclBnFr_setHashOf(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) == 0 +} + +// GetString -- +func (x *Fr) GetString(base int) string { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnFr_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) + if n == 0 { + panic("err mclBnFr_getStr") + } + return string(buf[:n]) +} + +// Serialize -- +func (x *Fr) Serialize() []byte { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnFr_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) + if n == 0 { + panic("err mclBnFr_serialize") + } + return buf[:n] +} + +// FrNeg -- +func FrNeg(out *Fr, x *Fr) { + C.mclBnFr_neg(out.getPointer(), x.getPointer()) +} + +// FrInv -- +func FrInv(out *Fr, x *Fr) { + C.mclBnFr_inv(out.getPointer(), x.getPointer()) +} + +// FrAdd -- +func FrAdd(out *Fr, x *Fr, y *Fr) { + C.mclBnFr_add(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// FrSub -- +func FrSub(out *Fr, x *Fr, y *Fr) { + C.mclBnFr_sub(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// FrMul -- +func FrMul(out *Fr, x *Fr, y *Fr) { + C.mclBnFr_mul(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// FrDiv -- +func FrDiv(out *Fr, x *Fr, y *Fr) { + C.mclBnFr_div(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G1 -- +type G1 struct { + v C.mclBnG1 +} + +// getPointer -- +func (x *G1) getPointer() (p *C.mclBnG1) { + // #nosec + return (*C.mclBnG1)(unsafe.Pointer(x)) +} + +// Clear -- +func (x *G1) Clear() { + // #nosec + C.mclBnG1_clear(x.getPointer()) +} + +// SetString -- +func (x *G1) SetString(s string, base int) error { + buf := []byte(s) + // #nosec + err := C.mclBnG1_setStr(x.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(base)) + if err != 0 { + return fmt.Errorf("err mclBnG1_setStr %x", err) + } + return nil +} + +// Deserialize -- +func (x *G1) Deserialize(buf []byte) error { + // #nosec + err := C.mclBnG1_deserialize(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err == 0 { + return fmt.Errorf("err mclBnG1_deserialize %x", buf) + } + return nil +} + +// IsEqual -- +func (x *G1) IsEqual(rhs *G1) bool { + return C.mclBnG1_isEqual(x.getPointer(), rhs.getPointer()) == 1 +} + +// IsZero -- +func (x *G1) IsZero() bool { + return C.mclBnG1_isZero(x.getPointer()) == 1 +} + +// HashAndMapTo -- +func (x *G1) HashAndMapTo(buf []byte) error { + // #nosec + err := C.mclBnG1_hashAndMapTo(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err != 0 { + return fmt.Errorf("err mclBnG1_hashAndMapTo %x", err) + } + return nil +} + +// GetString -- +func (x *G1) GetString(base int) string { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnG1_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) + if n == 0 { + panic("err mclBnG1_getStr") + } + return string(buf[:n]) +} + +// Serialize -- +func (x *G1) Serialize() []byte { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnG1_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) + if n == 0 { + panic("err mclBnG1_serialize") + } + return buf[:n] +} + +// G1Neg -- +func G1Neg(out *G1, x *G1) { + C.mclBnG1_neg(out.getPointer(), x.getPointer()) +} + +// G1Dbl -- +func G1Dbl(out *G1, x *G1) { + C.mclBnG1_dbl(out.getPointer(), x.getPointer()) +} + +// G1Add -- +func G1Add(out *G1, x *G1, y *G1) { + C.mclBnG1_add(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G1Sub -- +func G1Sub(out *G1, x *G1, y *G1) { + C.mclBnG1_sub(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G1Mul -- +func G1Mul(out *G1, x *G1, y *Fr) { + C.mclBnG1_mul(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G1MulCT -- constant time (depending on bit lengh of y) +func G1MulCT(out *G1, x *G1, y *Fr) { + C.mclBnG1_mulCT(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G2 -- +type G2 struct { + v C.mclBnG2 +} + +// getPointer -- +func (x *G2) getPointer() (p *C.mclBnG2) { + // #nosec + return (*C.mclBnG2)(unsafe.Pointer(x)) +} + +// Clear -- +func (x *G2) Clear() { + // #nosec + C.mclBnG2_clear(x.getPointer()) +} + +// SetString -- +func (x *G2) SetString(s string, base int) error { + buf := []byte(s) + // #nosec + err := C.mclBnG2_setStr(x.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(base)) + if err != 0 { + return fmt.Errorf("err mclBnG2_setStr %x", err) + } + return nil +} + +// Deserialize -- +func (x *G2) Deserialize(buf []byte) error { + // #nosec + err := C.mclBnG2_deserialize(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err == 0 { + return fmt.Errorf("err mclBnG2_deserialize %x", buf) + } + return nil +} + +// IsEqual -- +func (x *G2) IsEqual(rhs *G2) bool { + return C.mclBnG2_isEqual(x.getPointer(), rhs.getPointer()) == 1 +} + +// IsZero -- +func (x *G2) IsZero() bool { + return C.mclBnG2_isZero(x.getPointer()) == 1 +} + +// HashAndMapTo -- +func (x *G2) HashAndMapTo(buf []byte) error { + // #nosec + err := C.mclBnG2_hashAndMapTo(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err != 0 { + return fmt.Errorf("err mclBnG2_hashAndMapTo %x", err) + } + return nil +} + +// GetString -- +func (x *G2) GetString(base int) string { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnG2_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) + if n == 0 { + panic("err mclBnG2_getStr") + } + return string(buf[:n]) +} + +// Serialize -- +func (x *G2) Serialize() []byte { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnG2_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) + if n == 0 { + panic("err mclBnG2_serialize") + } + return buf[:n] +} + +// G2Neg -- +func G2Neg(out *G2, x *G2) { + C.mclBnG2_neg(out.getPointer(), x.getPointer()) +} + +// G2Dbl -- +func G2Dbl(out *G2, x *G2) { + C.mclBnG2_dbl(out.getPointer(), x.getPointer()) +} + +// G2Add -- +func G2Add(out *G2, x *G2, y *G2) { + C.mclBnG2_add(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G2Sub -- +func G2Sub(out *G2, x *G2, y *G2) { + C.mclBnG2_sub(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// G2Mul -- +func G2Mul(out *G2, x *G2, y *Fr) { + C.mclBnG2_mul(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// GT -- +type GT struct { + v C.mclBnGT +} + +// getPointer -- +func (x *GT) getPointer() (p *C.mclBnGT) { + // #nosec + return (*C.mclBnGT)(unsafe.Pointer(x)) +} + +// Clear -- +func (x *GT) Clear() { + // #nosec + C.mclBnGT_clear(x.getPointer()) +} + +// SetInt64 -- +func (x *GT) SetInt64(v int64) { + // #nosec + C.mclBnGT_setInt(x.getPointer(), C.int64_t(v)) +} + +// SetString -- +func (x *GT) SetString(s string, base int) error { + buf := []byte(s) + // #nosec + err := C.mclBnGT_setStr(x.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(base)) + if err != 0 { + return fmt.Errorf("err mclBnGT_setStr %x", err) + } + return nil +} + +// Deserialize -- +func (x *GT) Deserialize(buf []byte) error { + // #nosec + err := C.mclBnGT_deserialize(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if err == 0 { + return fmt.Errorf("err mclBnGT_deserialize %x", buf) + } + return nil +} + +// IsEqual -- +func (x *GT) IsEqual(rhs *GT) bool { + return C.mclBnGT_isEqual(x.getPointer(), rhs.getPointer()) == 1 +} + +// IsZero -- +func (x *GT) IsZero() bool { + return C.mclBnGT_isZero(x.getPointer()) == 1 +} + +// IsOne -- +func (x *GT) IsOne() bool { + return C.mclBnGT_isOne(x.getPointer()) == 1 +} + +// GetString -- +func (x *GT) GetString(base int) string { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnGT_getStr((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), x.getPointer(), C.int(base)) + if n == 0 { + panic("err mclBnGT_getStr") + } + return string(buf[:n]) +} + +// Serialize -- +func (x *GT) Serialize() []byte { + buf := make([]byte, 2048) + // #nosec + n := C.mclBnGT_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) + if n == 0 { + panic("err mclBnGT_serialize") + } + return buf[:n] +} + +// GTNeg -- +func GTNeg(out *GT, x *GT) { + C.mclBnGT_neg(out.getPointer(), x.getPointer()) +} + +// GTInv -- +func GTInv(out *GT, x *GT) { + C.mclBnGT_inv(out.getPointer(), x.getPointer()) +} + +// GTAdd -- +func GTAdd(out *GT, x *GT, y *GT) { + C.mclBnGT_add(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// GTSub -- +func GTSub(out *GT, x *GT, y *GT) { + C.mclBnGT_sub(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// GTMul -- +func GTMul(out *GT, x *GT, y *GT) { + C.mclBnGT_mul(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// GTDiv -- +func GTDiv(out *GT, x *GT, y *GT) { + C.mclBnGT_div(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// GTPow -- +func GTPow(out *GT, x *GT, y *Fr) { + C.mclBnGT_pow(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// Pairing -- +func Pairing(out *GT, x *G1, y *G2) { + C.mclBn_pairing(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// FinalExp -- +func FinalExp(out *GT, x *GT) { + C.mclBn_finalExp(out.getPointer(), x.getPointer()) +} + +// MillerLoop -- +func MillerLoop(out *GT, x *G1, y *G2) { + C.mclBn_millerLoop(out.getPointer(), x.getPointer(), y.getPointer()) +} + +// GetUint64NumToPrecompute -- +func GetUint64NumToPrecompute() int { + return int(C.mclBn_getUint64NumToPrecompute()) +} + +// PrecomputeG2 -- +func PrecomputeG2(Qbuf []uint64, Q *G2) { + // #nosec + C.mclBn_precomputeG2((*C.uint64_t)(unsafe.Pointer(&Qbuf[0])), Q.getPointer()) +} + +// PrecomputedMillerLoop -- +func PrecomputedMillerLoop(out *GT, P *G1, Qbuf []uint64) { + // #nosec + C.mclBn_precomputedMillerLoop(out.getPointer(), P.getPointer(), (*C.uint64_t)(unsafe.Pointer(&Qbuf[0]))) +} + +// PrecomputedMillerLoop2 -- +func PrecomputedMillerLoop2(out *GT, P1 *G1, Q1buf []uint64, P2 *G1, Q2buf []uint64) { + // #nosec + C.mclBn_precomputedMillerLoop2(out.getPointer(), P1.getPointer(), (*C.uint64_t)(unsafe.Pointer(&Q1buf[0])), P1.getPointer(), (*C.uint64_t)(unsafe.Pointer(&Q1buf[0]))) +} + +// FrEvaluatePolynomial -- y = c[0] + c[1] * x + c[2] * x^2 + ... +func FrEvaluatePolynomial(y *Fr, c []Fr, x *Fr) error { + // #nosec + err := C.mclBn_FrEvaluatePolynomial(y.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&c[0])), (C.size_t)(len(c)), x.getPointer()) + if err != 0 { + return fmt.Errorf("err mclBn_FrEvaluatePolynomial") + } + return nil +} + +// G1EvaluatePolynomial -- y = c[0] + c[1] * x + c[2] * x^2 + ... +func G1EvaluatePolynomial(y *G1, c []G1, x *Fr) error { + // #nosec + err := C.mclBn_G1EvaluatePolynomial(y.getPointer(), (*C.mclBnG1)(unsafe.Pointer(&c[0])), (C.size_t)(len(c)), x.getPointer()) + if err != 0 { + return fmt.Errorf("err mclBn_G1EvaluatePolynomial") + } + return nil +} + +// G2EvaluatePolynomial -- y = c[0] + c[1] * x + c[2] * x^2 + ... +func G2EvaluatePolynomial(y *G2, c []G2, x *Fr) error { + // #nosec + err := C.mclBn_G2EvaluatePolynomial(y.getPointer(), (*C.mclBnG2)(unsafe.Pointer(&c[0])), (C.size_t)(len(c)), x.getPointer()) + if err != 0 { + return fmt.Errorf("err mclBn_G2EvaluatePolynomial") + } + return nil +} + +// FrLagrangeInterpolation -- +func FrLagrangeInterpolation(out *Fr, xVec []Fr, yVec []Fr) error { + if len(xVec) != len(yVec) { + return fmt.Errorf("err FrLagrangeInterpolation:bad size") + } + // #nosec + err := C.mclBn_FrLagrangeInterpolation(out.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&xVec[0])), (*C.mclBnFr)(unsafe.Pointer(&yVec[0])), (C.size_t)(len(xVec))) + if err != 0 { + return fmt.Errorf("err FrLagrangeInterpolation") + } + return nil +} + +// G1LagrangeInterpolation -- +func G1LagrangeInterpolation(out *G1, xVec []Fr, yVec []G1) error { + if len(xVec) != len(yVec) { + return fmt.Errorf("err G1LagrangeInterpolation:bad size") + } + // #nosec + err := C.mclBn_G1LagrangeInterpolation(out.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&xVec[0])), (*C.mclBnG1)(unsafe.Pointer(&yVec[0])), (C.size_t)(len(xVec))) + if err != 0 { + return fmt.Errorf("err G1LagrangeInterpolation") + } + return nil +} + +// G2LagrangeInterpolation -- +func G2LagrangeInterpolation(out *G2, xVec []Fr, yVec []G2) error { + if len(xVec) != len(yVec) { + return fmt.Errorf("err G2LagrangeInterpolation:bad size") + } + // #nosec + err := C.mclBn_G2LagrangeInterpolation(out.getPointer(), (*C.mclBnFr)(unsafe.Pointer(&xVec[0])), (*C.mclBnG2)(unsafe.Pointer(&yVec[0])), (C.size_t)(len(xVec))) + if err != 0 { + return fmt.Errorf("err G2LagrangeInterpolation") + } + return nil +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/go/mcl/mcl_test.go b/vendor/github.com/dexon-foundation/mcl/ffi/go/mcl/mcl_test.go new file mode 100644 index 000000000..16bb6910f --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/go/mcl/mcl_test.go @@ -0,0 +1,157 @@ +package mcl + +import "testing" +import "fmt" + +func testBadPointOfG2(t *testing.T) { + var Q G2 + // this value is not in G2 so should return an error + err := Q.SetString("1 18d3d8c085a5a5e7553c3a4eb628e88b8465bf4de2612e35a0a4eb018fb0c82e9698896031e62fd7633ffd824a859474 1dc6edfcf33e29575d4791faed8e7203832217423bf7f7fbf1f6b36625b12e7132c15fbc15562ce93362a322fb83dd0d 65836963b1f7b6959030ddfa15ab38ce056097e91dedffd996c1808624fa7e2644a77be606290aa555cda8481cfb3cb 1b77b708d3d4f65aeedf54b58393463a42f0dc5856baadb5ce608036baeca398c5d9e6b169473a8838098fd72fd28b50", 16) + if err == nil { + t.Error(err) + } +} + +func testGT(t *testing.T) { + var x GT + x.Clear() + if !x.IsZero() { + t.Errorf("not zero") + } + x.SetInt64(1) + if !x.IsOne() { + t.Errorf("not one") + } +} + +func testHash(t *testing.T) { + var x Fr + if !x.SetHashOf([]byte("abc")) { + t.Error("SetHashOf") + } + fmt.Printf("x=%s\n", x.GetString(16)) +} + +func testNegAdd(t *testing.T) { + var x Fr + var P1, P2, P3 G1 + var Q1, Q2, Q3 G2 + err := P1.HashAndMapTo([]byte("this")) + if err != nil { + t.Error(err) + } + err = Q1.HashAndMapTo([]byte("this")) + if err != nil { + t.Error(err) + } + fmt.Printf("P1=%s\n", P1.GetString(16)) + fmt.Printf("Q1=%s\n", Q1.GetString(16)) + G1Neg(&P2, &P1) + G2Neg(&Q2, &Q1) + fmt.Printf("P2=%s\n", P2.GetString(16)) + fmt.Printf("Q2=%s\n", Q2.GetString(16)) + + x.SetInt64(-1) + G1Mul(&P3, &P1, &x) + G2Mul(&Q3, &Q1, &x) + if !P2.IsEqual(&P3) { + t.Errorf("P2 != P3 %s\n", P3.GetString(16)) + } + if !Q2.IsEqual(&Q3) { + t.Errorf("Q2 != Q3 %s\n", Q3.GetString(16)) + } + + G1Add(&P2, &P2, &P1) + G2Add(&Q2, &Q2, &Q1) + if !P2.IsZero() { + t.Errorf("P2 is not zero %s\n", P2.GetString(16)) + } + if !Q2.IsZero() { + t.Errorf("Q2 is not zero %s\n", Q2.GetString(16)) + } +} + +func testPairing(t *testing.T) { + var a, b, ab Fr + err := a.SetString("123", 10) + if err != nil { + t.Error(err) + return + } + err = b.SetString("456", 10) + if err != nil { + t.Error(err) + return + } + FrMul(&ab, &a, &b) + var P, aP G1 + var Q, bQ G2 + err = P.HashAndMapTo([]byte("this")) + if err != nil { + t.Error(err) + return + } + fmt.Printf("P=%s\n", P.GetString(16)) + G1Mul(&aP, &P, &a) + fmt.Printf("aP=%s\n", aP.GetString(16)) + err = Q.HashAndMapTo([]byte("that")) + if err != nil { + t.Error(err) + return + } + fmt.Printf("Q=%s\n", Q.GetString(16)) + G2Mul(&bQ, &Q, &b) + fmt.Printf("bQ=%s\n", bQ.GetString(16)) + var e1, e2 GT + Pairing(&e1, &P, &Q) + fmt.Printf("e1=%s\n", e1.GetString(16)) + Pairing(&e2, &aP, &bQ) + fmt.Printf("e2=%s\n", e1.GetString(16)) + GTPow(&e1, &e1, &ab) + fmt.Printf("e1=%s\n", e1.GetString(16)) + if !e1.IsEqual(&e2) { + t.Errorf("not equal pairing\n%s\n%s", e1.GetString(16), e2.GetString(16)) + } + { + s := P.GetString(IoSerializeHexStr) + var P1 G1 + P1.SetString(s, IoSerializeHexStr) + if !P1.IsEqual(&P) { + t.Error("not equal to P") + return + } + s = Q.GetString(IoSerializeHexStr) + var Q1 G2 + Q1.SetString(s, IoSerializeHexStr) + if !Q1.IsEqual(&Q) { + t.Error("not equal to Q") + return + } + } +} + +func testMcl(t *testing.T, c int) { + err := Init(c) + if err != nil { + t.Fatal(err) + } + testHash(t) + testNegAdd(t) + testPairing(t) + testGT(t) + testBadPointOfG2(t) +} + +func TestMclMain(t *testing.T) { + t.Logf("GetMaxOpUnitSize() = %d\n", GetMaxOpUnitSize()) + t.Log("CurveFp254BNb") + testMcl(t, CurveFp254BNb) + if GetMaxOpUnitSize() == 6 { + if GetFrUnitSize() == 6 { + t.Log("CurveFp382_1") + testMcl(t, CurveFp382_1) + } + t.Log("BLS12_381") + testMcl(t, BLS12_381) + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/Bn256Test.java b/vendor/github.com/dexon-foundation/mcl/ffi/java/Bn256Test.java new file mode 100644 index 000000000..b1f9f6f34 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/Bn256Test.java @@ -0,0 +1,104 @@ +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)); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/ElgamalTest.java b/vendor/github.com/dexon-foundation/mcl/ffi/java/ElgamalTest.java new file mode 100644 index 000000000..0cf49e144 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/ElgamalTest.java @@ -0,0 +1,144 @@ +import java.io.*; +import com.herumi.mcl.*; + +/* + ElgamalTest [ecParam] + ecParam = secp192k1, NIST_P224, ... + hashParam = hash224, hash384, ... +*/ +public class ElgamalTest { + static { + String lib = "mcl_elgamal"; + String libName = System.mapLibraryName(lib); + System.out.println("libName : " + libName); + System.loadLibrary(lib); + } + public static void assertEquals(String msg, int x, int y) { + if (x == 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 { + String ecStr = "secp192k1"; + String hashStr = "sha224"; + for (int i = 0; i < argv.length; i++) { + if (argv[i].equals("-e") && i < argv.length - 1) { + ecStr = argv[i + 1]; + i++; + } else + if (argv[i].equals("-h") && i < argv.length - 1) { + hashStr = argv[i + 1]; + i++; + } + } + String param = ecStr + " " + hashStr; + System.out.println("param=" + param); + Elgamal.SystemInit(param); + + String prvStr = ""; + String pubStr = ""; + { + PrivateKey prv = new PrivateKey(); + prv.init(); + prvStr = prv.toStr(); + PublicKey pub = prv.getPublicKey(); + pubStr = pub.toStr(); + } + int m = 1234; + CipherText c = new CipherText(); + PublicKey pub = new PublicKey(); + + pub.fromStr(pubStr); + + pub.enc(c, m); + + PrivateKey prv = new PrivateKey(); + prv.fromStr(prvStr); + prv.setCache(0, 60000); + + int dec = prv.dec(c); + // verify dec(enc(m)) == m + assertEquals("dec(enc(m)) == m", m, dec); + + // verify toStr, fromStr + { + String cStr = c.toStr(); + CipherText c2 = new CipherText(); + c2.fromStr(cStr); + int dec2 = prv.dec(c2); + assertEquals("fromStr(toStr(CipherText) == CipherText", dec, dec2); + } + + // verify dec(enc(str)) == str + pub.enc(c, "1234"); + dec = prv.dec(c); + assertEquals("dec(enc(str)) == str", m, dec); + + // verify dec(mul(enc(m), 3)) == m * 3 + c.mul(3); + m *= 3; + dec = prv.dec(c); + assertEquals("mul(int)", m, dec); + + // verify dec(mul(enc(m), "10")) == m * 10 + c.mul("10"); + m *= 10; + dec = prv.dec(c); + assertEquals("mul(str)", m, dec); + + // convert str + { + String s = c.toStr(); + CipherText c2 = new CipherText(); + c2.fromStr(s); + dec = prv.dec(c); + assertEquals("fromStr", m, dec); + } + // rerandomize + pub.rerandomize(c); + dec = prv.dec(c); + assertEquals("rerandomize", m, dec); + int m2 = 12345; + // verify dec(add(enc(m), m2)) == m + m2 + pub.add(c, m2); + m += m2; + dec = prv.dec(c); + assertEquals("pub.add(int)", m, dec); + + pub.add(c, "993"); + m += 993; + dec = prv.dec(c); + assertEquals("pub.add(str)", m, dec); + + // string test + String m3 = "-2000000"; + String m4 = "2001234"; + CipherText c2 = new CipherText(); + SWIGTYPE_p_bool b = Elgamal.new_p_bool(); + pub.enc(c, m3); + dec = prv.dec(c, b); + assertBool("expect dec fail", !Elgamal.p_bool_value(b)); + pub.enc(c2, m4); + dec = prv.dec(c2, b); + assertBool("expect dec fail", !Elgamal.p_bool_value(b)); + c.add(c2); // m3 + m4 + + dec = prv.dec(c, b); + assertEquals("int add", 1234, dec); + assertBool("expect dec success", Elgamal.p_bool_value(b)); + Elgamal.delete_p_bool(b); + } catch (RuntimeException e) { + System.out.println("unknown exception :" + e); + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/Makefile b/vendor/github.com/dexon-foundation/mcl/ffi/java/Makefile new file mode 100644 index 000000000..d69c043fb --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/Makefile @@ -0,0 +1,64 @@ +TOP_DIR=../.. +include $(TOP_DIR)/common.mk +ifeq ($(UNAME_S),Darwin) + JAVA_INC=-I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/ +else + JAVA_INC=-I/usr/lib/jvm/default-java/include +#JAVA_INC=-I/usr/lib/jvm/java-7-openjdk-amd64/include + CFLAGS+=-z noexecstack + LDFLAGS+=-lrt +endif +CFLAGS+=$(JAVA_INC) $(JAVA_INC)/linux -I $(TOP_DIR)/include -I $(TOP_DIR)/../xbyak -I $(TOP_DIR)/../cybozulib/include -Wno-strict-aliasing +MCL_LIB=$(TOP_DIR)/lib/libmcl.a + +PACKAGE_NAME=com.herumi.mcl +PACKAGE_DIR=$(subst .,/,$(PACKAGE_NAME)) + +ELGAMAL_LIB=$(TOP_DIR)/bin/libmcl_elgamal.$(LIB_SUF) +BN256_LIB=$(TOP_DIR)/bin/libmcl_bn256.$(LIB_SUF) +JAVA_EXE=cd $(TOP_DIR)/bin && LD_LIBRARY_PATH=./:$(LD_LIBRARY_PATH) java -classpath ../ffi/java +all: $(ELGAMAL_LIB) + +elgamal_wrap.cxx: elgamal.i elgamal_impl.hpp + $(MKDIR) $(PACKAGE_DIR) + swig -java -package $(PACKAGE_NAME) -outdir $(PACKAGE_DIR) -c++ -Wall elgamal.i + +bn256_wrap.cxx: bn256.i bn256_impl.hpp + $(MKDIR) $(PACKAGE_DIR) + swig -java -package $(PACKAGE_NAME) -outdir $(PACKAGE_DIR) -c++ -Wall bn256.i + +$(MCL_LIB): + make -C $(TOP_DIR) + +$(ELGAMAL_LIB): elgamal_wrap.cxx $(MCL_LIB) + $(PRE)$(CXX) $< -o $@ $(CFLAGS) $(LDFLAGS) $(MCL_LIB) -shared + +$(BN256_LIB): bn256_wrap.cxx $(MCL_LIB) + $(PRE)$(CXX) $< -o $@ $(CFLAGS) $(LDFLAGS) $(MCL_LIB) -shared + +%.class: %.java + javac $< + +ElgamalTest.class: ElgamalTest.java $(ELGAMAL_LIB) +Bn256Test.class: Bn256Test.java $(BN256_LIB) + +jar: + jar cvf mcl.jar com + +test_elgamal: ElgamalTest.class $(ELGAMAL_LIB) + $(JAVA_EXE) ElgamalTest + $(JAVA_EXE) ElgamalTest -e NIST_P192 + $(JAVA_EXE) ElgamalTest -e NIST_P256 -h sha256 + $(JAVA_EXE) ElgamalTest -e NIST_P384 -h sha384 + $(JAVA_EXE) ElgamalTest -e NIST_P521 -h sha512 + +test_bn256: Bn256Test.class $(BN256_LIB) + $(JAVA_EXE) Bn256Test + +test: + $(MAKE) test_elgamal + $(MAKE) test_bn256 + +clean: + rm -rf *.class $(ELGAMAL_LIB) $(PACKAGE_DIR)/*.class *_wrap.cxx + diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256.i b/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256.i new file mode 100644 index 000000000..94a8edb7a --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256.i @@ -0,0 +1,31 @@ +%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" diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256_impl.hpp b/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256_impl.hpp new file mode 100644 index 000000000..c4caaf3ca --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256_impl.hpp @@ -0,0 +1,249 @@ +#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_); +} diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256_wrap.cxx b/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256_wrap.cxx new file mode 100644 index 000000000..0c8257af5 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/bn256_wrap.cxx @@ -0,0 +1,1542 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 3.0.12 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + + +#ifndef SWIGJAVA +#define SWIGJAVA +#endif + + + +#ifdef __cplusplus +/* SwigValueWrapper is described in swig.swg */ +template<typename T> class SwigValueWrapper { + struct SwigMovePointer { + T *ptr; + SwigMovePointer(T *p) : ptr(p) { } + ~SwigMovePointer() { delete ptr; } + SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + } pointer; + SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs); + SwigValueWrapper(const SwigValueWrapper<T>& rhs); +public: + SwigValueWrapper() : pointer(0) { } + SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } + operator T&() const { return *pointer.ptr; } + T *operator&() { return pointer.ptr; } +}; + +template <typename T> T SwigValueInit() { + return T(); +} +#endif + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + + +/* Fix for jlong on some versions of gcc on Windows */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) + typedef long long __int64; +#endif + +/* Fix for jlong on 64-bit x86 Solaris */ +#if defined(__x86_64) +# ifdef _LP64 +# undef _LP64 +# endif +#endif + +#include <jni.h> +#include <stdlib.h> +#include <string.h> + + +/* Support for throwing Java exceptions */ +typedef enum { + SWIG_JavaOutOfMemoryError = 1, + SWIG_JavaIOException, + SWIG_JavaRuntimeException, + SWIG_JavaIndexOutOfBoundsException, + SWIG_JavaArithmeticException, + SWIG_JavaIllegalArgumentException, + SWIG_JavaNullPointerException, + SWIG_JavaDirectorPureVirtual, + SWIG_JavaUnknownError +} SWIG_JavaExceptionCodes; + +typedef struct { + SWIG_JavaExceptionCodes code; + const char *java_exception; +} SWIG_JavaExceptions_t; + + +static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { + jclass excep; + static const SWIG_JavaExceptions_t java_exceptions[] = { + { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, + { SWIG_JavaIOException, "java/io/IOException" }, + { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, + { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, + { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, + { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, + { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, + { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, + { SWIG_JavaUnknownError, "java/lang/UnknownError" }, + { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } + }; + const SWIG_JavaExceptions_t *except_ptr = java_exceptions; + + while (except_ptr->code != code && except_ptr->code) + except_ptr++; + + jenv->ExceptionClear(); + excep = jenv->FindClass(except_ptr->java_exception); + if (excep) + jenv->ThrowNew(excep, msg); +} + + +/* Contract support */ + +#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else + + +#include <string> + + +#include <typeinfo> +#include <stdexcept> + + +#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" + + +#ifdef __cplusplus +extern "C" { +#endif + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_SystemInit(JNIEnv *jenv, jclass jcls) { + (void)jenv; + (void)jcls; + try { + SystemInit(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_neg_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + Fr *arg1 = 0 ; + Fr *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(Fr **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr & reference is null"); + return ; + } + arg2 = *(Fr **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + neg(*arg1,(Fr const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_add_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + Fr *arg1 = 0 ; + Fr *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(Fr **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr & reference is null"); + return ; + } + arg2 = *(Fr **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + add(*arg1,(Fr const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_sub_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + Fr *arg1 = 0 ; + Fr *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(Fr **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr & reference is null"); + return ; + } + arg2 = *(Fr **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + sub(*arg1,(Fr const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_mul_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + Fr *arg1 = 0 ; + Fr *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(Fr **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr & reference is null"); + return ; + } + arg2 = *(Fr **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + mul(*arg1,(Fr const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_mul_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + G1 *arg1 = 0 ; + G1 *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(G1 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 & reference is null"); + return ; + } + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + mul(*arg1,(G1 const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_mul_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + G2 *arg1 = 0 ; + G2 *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(G2 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 & reference is null"); + return ; + } + arg2 = *(G2 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + mul(*arg1,(G2 const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_div(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + Fr *arg1 = 0 ; + Fr *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(Fr **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr & reference is null"); + return ; + } + arg2 = *(Fr **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + div(*arg1,(Fr const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_pow(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + GT *arg1 = 0 ; + GT *arg2 = 0 ; + Fr *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(GT **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT & reference is null"); + return ; + } + arg2 = *(GT **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT const & reference is null"); + return ; + } + arg3 = *(Fr **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return ; + } + pow(*arg1,(GT const &)*arg2,(Fr const &)*arg3); +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1Fr_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + Fr *result = 0 ; + + (void)jenv; + (void)jcls; + result = (Fr *)new Fr(); + *(Fr **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1Fr_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + Fr *arg1 = 0 ; + Fr *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(Fr **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return 0; + } + result = (Fr *)new Fr((Fr const &)*arg1); + *(Fr **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1Fr_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jint jarg1) { + jlong jresult = 0 ; + int arg1 ; + Fr *result = 0 ; + + (void)jenv; + (void)jcls; + arg1 = (int)jarg1; + result = (Fr *)new Fr(arg1); + *(Fr **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1Fr_1_1SWIG_13(JNIEnv *jenv, jclass jcls, jstring jarg1) { + jlong jresult = 0 ; + std::string *arg1 = 0 ; + Fr *result = 0 ; + + (void)jenv; + (void)jcls; + if(!jarg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg1_pstr = (const char *)jenv->GetStringUTFChars(jarg1, 0); + if (!arg1_pstr) return 0; + std::string arg1_str(arg1_pstr); + arg1 = &arg1_str; + jenv->ReleaseStringUTFChars(jarg1, arg1_pstr); + try { + result = (Fr *)new Fr((std::string const &)*arg1); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + *(Fr **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_herumi_mcl_Bn256JNI_Fr_1equals(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jboolean jresult = 0 ; + Fr *arg1 = (Fr *) 0 ; + Fr *arg2 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(Fr **)&jarg1; + arg2 = *(Fr **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Fr const & reference is null"); + return 0; + } + result = (bool)((Fr const *)arg1)->equals((Fr const &)*arg2); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_Fr_1setStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + Fr *arg1 = (Fr *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(Fr **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->setStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_Fr_1setInt(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + Fr *arg1 = (Fr *) 0 ; + int arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(Fr **)&jarg1; + arg2 = (int)jarg2; + (arg1)->setInt(arg2); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_Fr_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + Fr *arg1 = (Fr *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(Fr **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_Fr_1setRand(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + Fr *arg1 = (Fr *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(Fr **)&jarg1; + (arg1)->setRand(); +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_Bn256JNI_Fr_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + Fr *arg1 = (Fr *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(Fr **)&jarg1; + try { + result = ((Fr const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_delete_1Fr(JNIEnv *jenv, jclass jcls, jlong jarg1) { + Fr *arg1 = (Fr *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(Fr **)&jarg1; + delete arg1; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_neg_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + G1 *arg1 = 0 ; + G1 *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(G1 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 & reference is null"); + return ; + } + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + neg(*arg1,(G1 const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_dbl_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + G1 *arg1 = 0 ; + G1 *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(G1 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 & reference is null"); + return ; + } + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + dbl(*arg1,(G1 const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_add_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + G1 *arg1 = 0 ; + G1 *arg2 = 0 ; + G1 *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(G1 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 & reference is null"); + return ; + } + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + arg3 = *(G1 **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + add(*arg1,(G1 const &)*arg2,(G1 const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_sub_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + G1 *arg1 = 0 ; + G1 *arg2 = 0 ; + G1 *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(G1 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 & reference is null"); + return ; + } + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + arg3 = *(G1 **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + sub(*arg1,(G1 const &)*arg2,(G1 const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_pairing(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + GT *arg1 = 0 ; + G1 *arg2 = 0 ; + G2 *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(GT **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT & reference is null"); + return ; + } + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return ; + } + arg3 = *(G2 **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + pairing(*arg1,(G1 const &)*arg2,(G2 const &)*arg3); +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1G1_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + G1 *result = 0 ; + + (void)jenv; + (void)jcls; + result = (G1 *)new G1(); + *(G1 **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1G1_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + G1 *arg1 = 0 ; + G1 *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G1 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return 0; + } + result = (G1 *)new G1((G1 const &)*arg1); + *(G1 **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1G1_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2) { + jlong jresult = 0 ; + std::string *arg1 = 0 ; + std::string *arg2 = 0 ; + G1 *result = 0 ; + + (void)jenv; + (void)jcls; + if(!jarg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg1_pstr = (const char *)jenv->GetStringUTFChars(jarg1, 0); + if (!arg1_pstr) return 0; + std::string arg1_str(arg1_pstr); + arg1 = &arg1_str; + jenv->ReleaseStringUTFChars(jarg1, arg1_pstr); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + result = (G1 *)new G1((std::string const &)*arg1,(std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + *(G1 **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_herumi_mcl_Bn256JNI_G1_1equals(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jboolean jresult = 0 ; + G1 *arg1 = (G1 *) 0 ; + G1 *arg2 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(G1 **)&jarg1; + arg2 = *(G1 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G1 const & reference is null"); + return 0; + } + result = (bool)((G1 const *)arg1)->equals((G1 const &)*arg2); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G1_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jstring jarg3) { + G1 *arg1 = (G1 *) 0 ; + std::string *arg2 = 0 ; + std::string *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G1 **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return ; + std::string arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + (arg1)->set((std::string const &)*arg2,(std::string const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G1_1hashAndMapToG1(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + G1 *arg1 = (G1 *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G1 **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->hashAndMapToG1((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G1_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + G1 *arg1 = (G1 *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G1 **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G1_1setStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + G1 *arg1 = (G1 *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G1 **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->setStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_Bn256JNI_G1_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + G1 *arg1 = (G1 *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G1 **)&jarg1; + try { + result = ((G1 const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_delete_1G1(JNIEnv *jenv, jclass jcls, jlong jarg1) { + G1 *arg1 = (G1 *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(G1 **)&jarg1; + delete arg1; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_neg_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + G2 *arg1 = 0 ; + G2 *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(G2 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 & reference is null"); + return ; + } + arg2 = *(G2 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + neg(*arg1,(G2 const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_dbl_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + G2 *arg1 = 0 ; + G2 *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(G2 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 & reference is null"); + return ; + } + arg2 = *(G2 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + dbl(*arg1,(G2 const &)*arg2); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_add_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + G2 *arg1 = 0 ; + G2 *arg2 = 0 ; + G2 *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(G2 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 & reference is null"); + return ; + } + arg2 = *(G2 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + arg3 = *(G2 **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + add(*arg1,(G2 const &)*arg2,(G2 const &)*arg3); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_sub_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + G2 *arg1 = 0 ; + G2 *arg2 = 0 ; + G2 *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(G2 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 & reference is null"); + return ; + } + arg2 = *(G2 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + arg3 = *(G2 **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return ; + } + sub(*arg1,(G2 const &)*arg2,(G2 const &)*arg3); +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1G2_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + G2 *result = 0 ; + + (void)jenv; + (void)jcls; + result = (G2 *)new G2(); + *(G2 **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1G2_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + G2 *arg1 = 0 ; + G2 *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G2 **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return 0; + } + result = (G2 *)new G2((G2 const &)*arg1); + *(G2 **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1G2_1_1SWIG_12(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2, jstring jarg3, jstring jarg4) { + jlong jresult = 0 ; + std::string *arg1 = 0 ; + std::string *arg2 = 0 ; + std::string *arg3 = 0 ; + std::string *arg4 = 0 ; + G2 *result = 0 ; + + (void)jenv; + (void)jcls; + if(!jarg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg1_pstr = (const char *)jenv->GetStringUTFChars(jarg1, 0); + if (!arg1_pstr) return 0; + std::string arg1_str(arg1_pstr); + arg1 = &arg1_str; + jenv->ReleaseStringUTFChars(jarg1, arg1_pstr); + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return 0; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return 0; + std::string arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + if(!jarg4) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return 0; + } + const char *arg4_pstr = (const char *)jenv->GetStringUTFChars(jarg4, 0); + if (!arg4_pstr) return 0; + std::string arg4_str(arg4_pstr); + arg4 = &arg4_str; + jenv->ReleaseStringUTFChars(jarg4, arg4_pstr); + try { + result = (G2 *)new G2((std::string const &)*arg1,(std::string const &)*arg2,(std::string const &)*arg3,(std::string const &)*arg4); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + *(G2 **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_herumi_mcl_Bn256JNI_G2_1equals(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jboolean jresult = 0 ; + G2 *arg1 = (G2 *) 0 ; + G2 *arg2 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(G2 **)&jarg1; + arg2 = *(G2 **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "G2 const & reference is null"); + return 0; + } + result = (bool)((G2 const *)arg1)->equals((G2 const &)*arg2); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G2_1set(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2, jstring jarg3, jstring jarg4, jstring jarg5) { + G2 *arg1 = (G2 *) 0 ; + std::string *arg2 = 0 ; + std::string *arg3 = 0 ; + std::string *arg4 = 0 ; + std::string *arg5 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G2 **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return ; + std::string arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + if(!jarg4) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg4_pstr = (const char *)jenv->GetStringUTFChars(jarg4, 0); + if (!arg4_pstr) return ; + std::string arg4_str(arg4_pstr); + arg4 = &arg4_str; + jenv->ReleaseStringUTFChars(jarg4, arg4_pstr); + if(!jarg5) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg5_pstr = (const char *)jenv->GetStringUTFChars(jarg5, 0); + if (!arg5_pstr) return ; + std::string arg5_str(arg5_pstr); + arg5 = &arg5_str; + jenv->ReleaseStringUTFChars(jarg5, arg5_pstr); + (arg1)->set((std::string const &)*arg2,(std::string const &)*arg3,(std::string const &)*arg4,(std::string const &)*arg5); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G2_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + G2 *arg1 = (G2 *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G2 **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_G2_1setStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + G2 *arg1 = (G2 *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G2 **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->setStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_Bn256JNI_G2_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + G2 *arg1 = (G2 *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(G2 **)&jarg1; + try { + result = ((G2 const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_delete_1G2(JNIEnv *jenv, jclass jcls, jlong jarg1) { + G2 *arg1 = (G2 *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(G2 **)&jarg1; + delete arg1; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_mul_1_1SWIG_13(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3, jobject jarg3_) { + GT *arg1 = 0 ; + GT *arg2 = 0 ; + GT *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + (void)jarg3_; + arg1 = *(GT **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT & reference is null"); + return ; + } + arg2 = *(GT **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT const & reference is null"); + return ; + } + arg3 = *(GT **)&jarg3; + if (!arg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT const & reference is null"); + return ; + } + mul(*arg1,(GT const &)*arg2,(GT const &)*arg3); +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1GT_1_1SWIG_10(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + GT *result = 0 ; + + (void)jenv; + (void)jcls; + result = (GT *)new GT(); + *(GT **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_Bn256JNI_new_1GT_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + GT *arg1 = 0 ; + GT *result = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(GT **)&jarg1; + if (!arg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT const & reference is null"); + return 0; + } + result = (GT *)new GT((GT const &)*arg1); + *(GT **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jboolean JNICALL Java_com_herumi_mcl_Bn256JNI_GT_1equals(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jboolean jresult = 0 ; + GT *arg1 = (GT *) 0 ; + GT *arg2 = 0 ; + bool result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(GT **)&jarg1; + arg2 = *(GT **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "GT const & reference is null"); + return 0; + } + result = (bool)((GT const *)arg1)->equals((GT const &)*arg2); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_GT_1clear(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + GT *arg1 = (GT *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(GT **)&jarg1; + (arg1)->clear(); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_GT_1setStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + GT *arg1 = (GT *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(GT **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->setStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_Bn256JNI_GT_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + GT *arg1 = (GT *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(GT **)&jarg1; + try { + result = ((GT const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_Bn256JNI_delete_1GT(JNIEnv *jenv, jclass jcls, jlong jarg1) { + GT *arg1 = (GT *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(GT **)&jarg1; + delete arg1; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal.i b/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal.i new file mode 100644 index 000000000..410723174 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal.i @@ -0,0 +1,28 @@ +%module Elgamal + +%include "std_string.i" +%include "std_except.i" + + +%{ +#include <cybozu/random_generator.hpp> +#include <cybozu/crypto.hpp> +#include <mcl/fp.hpp> +#include <mcl/ecparam.hpp> +struct Param { +const mcl::EcParam *ecParam; +cybozu::RandomGenerator rg; +cybozu::crypto::Hash::Name hashName; +static inline Param& getParam() +{ + static Param p; + return p; +} +}; + +#include "elgamal_impl.hpp" +%} +%include cpointer.i +%pointer_functions(bool, p_bool); + +%include "elgamal_impl.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal_impl.hpp b/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal_impl.hpp new file mode 100644 index 000000000..dbf2ba64e --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal_impl.hpp @@ -0,0 +1,147 @@ +#pragma once +//#define MCL_MAX_BIT_SIZE 521 +#include <iostream> +#include <fstream> +#include <cybozu/random_generator.hpp> +#include <cybozu/crypto.hpp> +#include <mcl/fp.hpp> +#include <mcl/ecparam.hpp> +#include <mcl/elgamal.hpp> + +typedef mcl::FpT<mcl::FpTag, 521> Fp; +typedef mcl::FpT<mcl::ZnTag, 521> Zn; +typedef mcl::EcT<Fp> Ec; +typedef mcl::ElgamalT<Ec, Zn> Elgamal; + +/* + init system + @param param [in] string such as "ecParamName hashName" + @note NOT thread safe because setting global parameters of elliptic curve + ex1) "secp192k1 sha256" // 192bit security + sha256 + ex2) "secp160k1 sha1" // 160bit security + sha1 + hashName : sha1 sha224 sha256 sha384 sha512 +*/ +void SystemInit(const std::string& param) throw(std::exception) +{ + std::istringstream iss(param); + std::string ecParamStr; + std::string hashNameStr; + if (iss >> ecParamStr >> hashNameStr) { + Param& p = Param::getParam(); + p.ecParam = mcl::getEcParam(ecParamStr); + Zn::init(p.ecParam->n); + Fp::init(p.ecParam->p); + Ec::init(p.ecParam->a, p.ecParam->b); + p.hashName = cybozu::crypto::Hash::getName(hashNameStr); + return; + } + throw cybozu::Exception("SystemInit:bad param") << param; +} + +class CipherText { + Elgamal::CipherText self_; + friend class PublicKey; + friend class PrivateKey; +public: + std::string toStr() const throw(std::exception) { return self_.toStr(); } + std::string toString() const throw(std::exception) { return toStr(); } + void fromStr(const std::string& str) throw(std::exception) { self_.fromStr(str); } + + void add(const CipherText& c) throw(std::exception) { self_.add(c.self_); } + void mul(int m) throw(std::exception) + { + self_.mul(m); + } + void mul(const std::string& str) throw(std::exception) + { + Zn zn(str); + self_.mul(zn); + } +}; + +class PublicKey { + Elgamal::PublicKey self_; + friend class PrivateKey; +public: + std::string toStr() const throw(std::exception) { return self_.toStr(); } + std::string toString() const throw(std::exception) { return toStr(); } + void fromStr(const std::string& str) throw(std::exception) { self_.fromStr(str); } + + void save(const std::string& fileName) const throw(std::exception) + { + std::ofstream ofs(fileName.c_str(), std::ios::binary); + if (!(ofs << self_)) throw cybozu::Exception("PublicKey:save") << fileName; + } + void load(const std::string& fileName) throw(std::exception) + { + std::ifstream ifs(fileName.c_str(), std::ios::binary); + if (!(ifs >> self_)) throw cybozu::Exception("PublicKey:load") << fileName; + } + void enc(CipherText& c, int m) const throw(std::exception) + { + self_.enc(c.self_, m, Param::getParam().rg); + } + void enc(CipherText& c, const std::string& str) const throw(std::exception) + { + Zn zn(str); + self_.enc(c.self_, zn, Param::getParam().rg); + } + void rerandomize(CipherText& c) const throw(std::exception) + { + self_.rerandomize(c.self_, Param::getParam().rg); + } + void add(CipherText& c, int m) const throw(std::exception) + { + self_.add(c.self_, m); + } + void add(CipherText& c, const std::string& str) const throw(std::exception) + { + Zn zn(str); + self_.add(c.self_, zn); + } +}; + +class PrivateKey { + Elgamal::PrivateKey self_; +public: + std::string toStr() const throw(std::exception) { return self_.toStr(); } + std::string toString() const throw(std::exception) { return toStr(); } + void fromStr(const std::string& str) throw(std::exception) { self_.fromStr(str); } + + void save(const std::string& fileName) const throw(std::exception) + { + std::ofstream ofs(fileName.c_str(), std::ios::binary); + if (!(ofs << self_)) throw cybozu::Exception("PrivateKey:save") << fileName; + } + void load(const std::string& fileName) throw(std::exception) + { + std::ifstream ifs(fileName.c_str(), std::ios::binary); + if (!(ifs >> self_)) throw cybozu::Exception("PrivateKey:load") << fileName; + } + void init() throw(std::exception) + { + Param& p = Param::getParam(); + const Fp x0(p.ecParam->gx); + const Fp y0(p.ecParam->gy); + Ec P(x0, y0); + self_.init(P, Zn::getBitSize(), p.rg); + } + PublicKey getPublicKey() const throw(std::exception) + { + PublicKey ret; + ret.self_ = self_.getPublicKey(); + return ret; + } + int dec(const CipherText& c, bool *b = 0) const throw(std::exception) + { + return self_.dec(c.self_, b); + } + void setCache(int rangeMin, int rangeMax) throw(std::exception) + { + self_.setCache(rangeMin, rangeMax); + } + void clearCache() throw(std::exception) + { + self_.clearCache(); + } +}; diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal_wrap.cxx b/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal_wrap.cxx new file mode 100644 index 000000000..38d05f489 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/elgamal_wrap.cxx @@ -0,0 +1,1129 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 3.0.12 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + + +#ifndef SWIGJAVA +#define SWIGJAVA +#endif + + + +#ifdef __cplusplus +/* SwigValueWrapper is described in swig.swg */ +template<typename T> class SwigValueWrapper { + struct SwigMovePointer { + T *ptr; + SwigMovePointer(T *p) : ptr(p) { } + ~SwigMovePointer() { delete ptr; } + SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + } pointer; + SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs); + SwigValueWrapper(const SwigValueWrapper<T>& rhs); +public: + SwigValueWrapper() : pointer(0) { } + SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } + operator T&() const { return *pointer.ptr; } + T *operator&() { return pointer.ptr; } +}; + +template <typename T> T SwigValueInit() { + return T(); +} +#endif + +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + + +/* Fix for jlong on some versions of gcc on Windows */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) + typedef long long __int64; +#endif + +/* Fix for jlong on 64-bit x86 Solaris */ +#if defined(__x86_64) +# ifdef _LP64 +# undef _LP64 +# endif +#endif + +#include <jni.h> +#include <stdlib.h> +#include <string.h> + + +/* Support for throwing Java exceptions */ +typedef enum { + SWIG_JavaOutOfMemoryError = 1, + SWIG_JavaIOException, + SWIG_JavaRuntimeException, + SWIG_JavaIndexOutOfBoundsException, + SWIG_JavaArithmeticException, + SWIG_JavaIllegalArgumentException, + SWIG_JavaNullPointerException, + SWIG_JavaDirectorPureVirtual, + SWIG_JavaUnknownError +} SWIG_JavaExceptionCodes; + +typedef struct { + SWIG_JavaExceptionCodes code; + const char *java_exception; +} SWIG_JavaExceptions_t; + + +static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { + jclass excep; + static const SWIG_JavaExceptions_t java_exceptions[] = { + { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, + { SWIG_JavaIOException, "java/io/IOException" }, + { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, + { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, + { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, + { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, + { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, + { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, + { SWIG_JavaUnknownError, "java/lang/UnknownError" }, + { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } + }; + const SWIG_JavaExceptions_t *except_ptr = java_exceptions; + + while (except_ptr->code != code && except_ptr->code) + except_ptr++; + + jenv->ExceptionClear(); + excep = jenv->FindClass(except_ptr->java_exception); + if (excep) + jenv->ThrowNew(excep, msg); +} + + +/* Contract support */ + +#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else + + +#include <string> + + +#include <typeinfo> +#include <stdexcept> + + +#include <cybozu/random_generator.hpp> +#include <cybozu/crypto.hpp> +#include <mcl/fp.hpp> +#include <mcl/ecparam.hpp> +struct Param { +const mcl::EcParam *ecParam; +cybozu::RandomGenerator rg; +cybozu::crypto::Hash::Name hashName; +static inline Param& getParam() +{ + static Param p; + return p; +} +}; + +#include "elgamal_impl.hpp" + + +static bool *new_p_bool() { + return new bool(); +} + +static bool *copy_p_bool(bool value) { + return new bool(value); +} + +static void delete_p_bool(bool *obj) { + if (obj) delete obj; +} + +static void p_bool_assign(bool *obj, bool value) { + *obj = value; +} + +static bool p_bool_value(bool *obj) { + return *obj; +} + + +#ifdef __cplusplus +extern "C" { +#endif + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_ElgamalJNI_new_1p_1bool(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + bool *result = 0 ; + + (void)jenv; + (void)jcls; + result = (bool *)new_p_bool(); + *(bool **)&jresult = result; + return jresult; +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_ElgamalJNI_copy_1p_1bool(JNIEnv *jenv, jclass jcls, jboolean jarg1) { + jlong jresult = 0 ; + bool arg1 ; + bool *result = 0 ; + + (void)jenv; + (void)jcls; + arg1 = jarg1 ? true : false; + result = (bool *)copy_p_bool(arg1); + *(bool **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_delete_1p_1bool(JNIEnv *jenv, jclass jcls, jlong jarg1) { + bool *arg1 = (bool *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(bool **)&jarg1; + delete_p_bool(arg1); +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_p_1bool_1assign(JNIEnv *jenv, jclass jcls, jlong jarg1, jboolean jarg2) { + bool *arg1 = (bool *) 0 ; + bool arg2 ; + + (void)jenv; + (void)jcls; + arg1 = *(bool **)&jarg1; + arg2 = jarg2 ? true : false; + p_bool_assign(arg1,arg2); +} + + +SWIGEXPORT jboolean JNICALL Java_com_herumi_mcl_ElgamalJNI_p_1bool_1value(JNIEnv *jenv, jclass jcls, jlong jarg1) { + jboolean jresult = 0 ; + bool *arg1 = (bool *) 0 ; + bool result; + + (void)jenv; + (void)jcls; + arg1 = *(bool **)&jarg1; + result = (bool)p_bool_value(arg1); + jresult = (jboolean)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_SystemInit(JNIEnv *jenv, jclass jcls, jstring jarg1) { + std::string *arg1 = 0 ; + + (void)jenv; + (void)jcls; + if(!jarg1) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg1_pstr = (const char *)jenv->GetStringUTFChars(jarg1, 0); + if (!arg1_pstr) return ; + std::string arg1_str(arg1_pstr); + arg1 = &arg1_str; + jenv->ReleaseStringUTFChars(jarg1, arg1_pstr); + try { + SystemInit((std::string const &)*arg1); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_ElgamalJNI_CipherText_1toStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + CipherText *arg1 = (CipherText *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(CipherText **)&jarg1; + try { + result = ((CipherText const *)arg1)->toStr(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_ElgamalJNI_CipherText_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + CipherText *arg1 = (CipherText *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(CipherText **)&jarg1; + try { + result = ((CipherText const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_CipherText_1fromStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + CipherText *arg1 = (CipherText *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(CipherText **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->fromStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_CipherText_1add(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + CipherText *arg1 = (CipherText *) 0 ; + CipherText *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(CipherText **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText const & reference is null"); + return ; + } + try { + (arg1)->add((CipherText const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_CipherText_1mul_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) { + CipherText *arg1 = (CipherText *) 0 ; + int arg2 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(CipherText **)&jarg1; + arg2 = (int)jarg2; + try { + (arg1)->mul(arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_CipherText_1mul_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + CipherText *arg1 = (CipherText *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(CipherText **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->mul((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_ElgamalJNI_new_1CipherText(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + CipherText *result = 0 ; + + (void)jenv; + (void)jcls; + result = (CipherText *)new CipherText(); + *(CipherText **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_delete_1CipherText(JNIEnv *jenv, jclass jcls, jlong jarg1) { + CipherText *arg1 = (CipherText *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(CipherText **)&jarg1; + delete arg1; +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1toStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + PublicKey *arg1 = (PublicKey *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PublicKey **)&jarg1; + try { + result = ((PublicKey const *)arg1)->toStr(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + PublicKey *arg1 = (PublicKey *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PublicKey **)&jarg1; + try { + result = ((PublicKey const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1fromStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + PublicKey *arg1 = (PublicKey *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PublicKey **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->fromStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1save(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + PublicKey *arg1 = (PublicKey *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PublicKey **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + ((PublicKey const *)arg1)->save((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1load(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + PublicKey *arg1 = (PublicKey *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PublicKey **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->load((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1enc_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jint jarg3) { + PublicKey *arg1 = (PublicKey *) 0 ; + CipherText *arg2 = 0 ; + int arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PublicKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText & reference is null"); + return ; + } + arg3 = (int)jarg3; + try { + ((PublicKey const *)arg1)->enc(*arg2,arg3); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1enc_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jstring jarg3) { + PublicKey *arg1 = (PublicKey *) 0 ; + CipherText *arg2 = 0 ; + std::string *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PublicKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText & reference is null"); + return ; + } + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return ; + std::string arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + try { + ((PublicKey const *)arg1)->enc(*arg2,(std::string const &)*arg3); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1rerandomize(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + PublicKey *arg1 = (PublicKey *) 0 ; + CipherText *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PublicKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText & reference is null"); + return ; + } + try { + ((PublicKey const *)arg1)->rerandomize(*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1add_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jint jarg3) { + PublicKey *arg1 = (PublicKey *) 0 ; + CipherText *arg2 = 0 ; + int arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PublicKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText & reference is null"); + return ; + } + arg3 = (int)jarg3; + try { + ((PublicKey const *)arg1)->add(*arg2,arg3); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PublicKey_1add_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jstring jarg3) { + PublicKey *arg1 = (PublicKey *) 0 ; + CipherText *arg2 = 0 ; + std::string *arg3 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PublicKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText & reference is null"); + return ; + } + if(!jarg3) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg3_pstr = (const char *)jenv->GetStringUTFChars(jarg3, 0); + if (!arg3_pstr) return ; + std::string arg3_str(arg3_pstr); + arg3 = &arg3_str; + jenv->ReleaseStringUTFChars(jarg3, arg3_pstr); + try { + ((PublicKey const *)arg1)->add(*arg2,(std::string const &)*arg3); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_ElgamalJNI_new_1PublicKey(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + PublicKey *result = 0 ; + + (void)jenv; + (void)jcls; + result = (PublicKey *)new PublicKey(); + *(PublicKey **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_delete_1PublicKey(JNIEnv *jenv, jclass jcls, jlong jarg1) { + PublicKey *arg1 = (PublicKey *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(PublicKey **)&jarg1; + delete arg1; +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1toStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + PrivateKey *arg1 = (PrivateKey *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + try { + result = ((PrivateKey const *)arg1)->toStr(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT jstring JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1toString(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jstring jresult = 0 ; + PrivateKey *arg1 = (PrivateKey *) 0 ; + std::string result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + try { + result = ((PrivateKey const *)arg1)->toString(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = jenv->NewStringUTF((&result)->c_str()); + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1fromStr(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->fromStr((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1save(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + ((PrivateKey const *)arg1)->save((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1load(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + std::string *arg2 = 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + if(!jarg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string"); + return ; + } + const char *arg2_pstr = (const char *)jenv->GetStringUTFChars(jarg2, 0); + if (!arg2_pstr) return ; + std::string arg2_str(arg2_pstr); + arg2 = &arg2_str; + jenv->ReleaseStringUTFChars(jarg2, arg2_pstr); + try { + (arg1)->load((std::string const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1init(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + try { + (arg1)->init(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1getPublicKey(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + jlong jresult = 0 ; + PrivateKey *arg1 = (PrivateKey *) 0 ; + PublicKey result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + try { + result = ((PrivateKey const *)arg1)->getPublicKey(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + *(PublicKey **)&jresult = new PublicKey((const PublicKey &)result); + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1dec_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_, jlong jarg3) { + jint jresult = 0 ; + PrivateKey *arg1 = (PrivateKey *) 0 ; + CipherText *arg2 = 0 ; + bool *arg3 = (bool *) 0 ; + int result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PrivateKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText const & reference is null"); + return 0; + } + arg3 = *(bool **)&jarg3; + try { + result = (int)((PrivateKey const *)arg1)->dec((CipherText const &)*arg2,arg3); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT jint JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1dec_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2, jobject jarg2_) { + jint jresult = 0 ; + PrivateKey *arg1 = (PrivateKey *) 0 ; + CipherText *arg2 = 0 ; + int result; + + (void)jenv; + (void)jcls; + (void)jarg1_; + (void)jarg2_; + arg1 = *(PrivateKey **)&jarg1; + arg2 = *(CipherText **)&jarg2; + if (!arg2) { + SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "CipherText const & reference is null"); + return 0; + } + try { + result = (int)((PrivateKey const *)arg1)->dec((CipherText const &)*arg2); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return 0; + } + + jresult = (jint)result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1setCache(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + int arg2 ; + int arg3 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + arg2 = (int)jarg2; + arg3 = (int)jarg3; + try { + (arg1)->setCache(arg2,arg3); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_PrivateKey_1clearCache(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + + (void)jenv; + (void)jcls; + (void)jarg1_; + arg1 = *(PrivateKey **)&jarg1; + try { + (arg1)->clearCache(); + } + catch(std::exception &_e) { + SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, (&_e)->what()); + return ; + } + +} + + +SWIGEXPORT jlong JNICALL Java_com_herumi_mcl_ElgamalJNI_new_1PrivateKey(JNIEnv *jenv, jclass jcls) { + jlong jresult = 0 ; + PrivateKey *result = 0 ; + + (void)jenv; + (void)jcls; + result = (PrivateKey *)new PrivateKey(); + *(PrivateKey **)&jresult = result; + return jresult; +} + + +SWIGEXPORT void JNICALL Java_com_herumi_mcl_ElgamalJNI_delete_1PrivateKey(JNIEnv *jenv, jclass jcls, jlong jarg1) { + PrivateKey *arg1 = (PrivateKey *) 0 ; + + (void)jenv; + (void)jcls; + arg1 = *(PrivateKey **)&jarg1; + delete arg1; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/java.md b/vendor/github.com/dexon-foundation/mcl/ffi/java/java.md new file mode 100644 index 000000000..3fe861351 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/java.md @@ -0,0 +1,95 @@ +# JNI for mcl (experimental) +This library provides functionality to compute the optimal ate pairing +over Barreto-Naehrig (BN) curves. + +# Initialization +Load the library `mcl_bn256`. +``` +import com.herumi.mcl.*; + +System.loadLibrary("mcl_bn256"); +``` + +# Classes +* `G1` ; The cyclic group instantiated as E(Fp)[r] where where r = p + 1 - t. +* `G2` ; The cyclic group instantiated as the inverse image of E'(Fp^2)[r]. +* `GT` ; The cyclic group in the image of the optimal ate pairing. + * `e : G1 x G2 -> GT` +* `Fr` ; The finite field with characteristic r. + +# Methods and Functions +## Fr +* `Fr::setInt(int x)` ; set by x +* `Fr::setStr(String str)` ; set by str such as "123", "0xfff", etc. +* `Fr::setRand()` ; randomly set +* `Bn256.neg(Fr y, Fr x)` ; `y = -x` +* `Bn256.add(Fr z, Fr x, Fr y)` ; `z = x + y` +* `Bn256.sub(Fr z, Fr x, Fr y)` ; `z = x - y` +* `Bn256.mul(Fr z, Fr x, Fr y)` ; `z = x * y` +* `Bn256.div(Fr z, Fr x, Fr y)` ; `z = x / y` + +## G1 + +* `G1::set(String x, String y)` ; set by (x, y) +* `G1::hashAndMapToG1(String m)` ; take SHA-256 of m and map it to an element of G1 +* `G1::setStr(String str)` ; set by the result of `toString()` method +* `Bn256.neg(G1 y, G1 x)` ; `y = -x` +* `Bn256.dbl(G1 y, G1 x)` ; `y = 2x` +* `Bn256.add(G1 z, G1 x, G1 y)` ; `z = x + y` +* `Bn256.sub(G1 z, G1 x, G1 y)` ; `z = x - y` +* `Bn256.mul(G1 z, G1 x, Fr y)` ; `z = x * y` + +## G2 + +* `G2::set(String xa, String xb, String ya, String yb)` ; set by ((xa, xb), (ya, yb)) +* `G2::setStr(String str)` ; set by the result of `toString()` method +* `Bn256.neg(G2 y, G2 x)` ; `y = -x` +* `Bn256.dbl(G2 y, G2 x)` ; `y = 2x` +* `Bn256.add(G2 z, G2 x, G2 y)` ; `z = x + y` +* `Bn256.sub(G2 z, G2 x, G2 y)` ; `z = x - y` +* `Bn256.mul(G2 z, G2 x, Fr y)` ; `z = x * y` + +## GT + +* `GT::setStr(String str)` ; set by the result of `toString()` method +* `Bn256.mul(GT z, GT x, GT y)` ; `z = x * y` +* `Bn256.pow(GT z, GT x, Fr y)` ; `z = x ^ y` + +## pairing +* `Bn256.pairing(GT e, G1 P, G2 Q)` ; e = e(P, Q) + +# BLS signature sample +``` +String xa = "12723517038133731887338407189719511622662176727675373276651903807414909099441"; +String xb = "4168783608814932154536427934509895782246573715297911553964171371032945126671"; +String ya = "13891744915211034074451795021214165905772212241412891944830863846330766296736"; +String yb = "7937318970632701341203597196594272556916396164729705624521405069090520231616"; + +G2 Q = new G2(xa, xb, ya, yb); // fixed point of G2 + +Fr s = new Fr(); +s.setRand(); // secret key +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)); +``` + +# Make test +``` +cd java +make test_bn256 +``` + +# Sample code +[Bn256Test.java](https://github.com/herumi/mcl/blob/master/java/Bn256Test.java) diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/make_wrap.bat b/vendor/github.com/dexon-foundation/mcl/ffi/java/make_wrap.bat new file mode 100644 index 000000000..b7008bc02 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/make_wrap.bat @@ -0,0 +1,23 @@ +@echo off +call set-java-path.bat +set JAVA_INCLUDE=%JAVA_DIR%\include +set SWIG=..\..\..\..\p\swig\swig.exe +set PACKAGE_NAME=com.herumi.mcl +set PACKAGE_DIR=%PACKAGE_NAME:.=\% +if /i "%1"=="" ( + set NAME=elgamal +) else ( + set NAME=%1 +) + +echo [[run swig]] +mkdir %PACKAGE_DIR% +set TOP_DIR=../.. +%SWIG% -java -package %PACKAGE_NAME% -outdir %PACKAGE_DIR% -c++ -Wall %NAME%.i +echo [[make dll]] +cl /MT /DNOMINMAX /LD /Ox /DNDEBUG /EHsc %NAME%_wrap.cxx %TOP_DIR%/src/fp.cpp -DMCL_NO_AUTOLINK -I%JAVA_INCLUDE% -I%JAVA_INCLUDE%\win32 -I%TOP_DIR%/include -I%TOP_DIR%/../cybozulib/include -I%TOP_DIR%/../cybozulib_ext/include -I%TOP_DIR%/../xbyak /link /LIBPATH:%TOP_DIR%/../cybozulib_ext/lib /OUT:%TOP_DIR%/bin/mcl_%NAME%.dll + +call run-%NAME%.bat + +echo [[make jar]] +%JAVA_DIR%\bin\jar cvf mcl.jar com diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/run-bn256.bat b/vendor/github.com/dexon-foundation/mcl/ffi/java/run-bn256.bat new file mode 100644 index 000000000..903876ec6 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/run-bn256.bat @@ -0,0 +1,9 @@ +@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 diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/run-elgamal.bat b/vendor/github.com/dexon-foundation/mcl/ffi/java/run-elgamal.bat new file mode 100644 index 000000000..8b889a64c --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/run-elgamal.bat @@ -0,0 +1,9 @@ +@echo off +echo [[compile ElgamalTest.java]] +%JAVA_DIR%\bin\javac ElgamalTest.java + +echo [[run ElgamalTest]] +set TOP_DIR=..\.. +pushd %TOP_DIR%\bin +%JAVA_DIR%\bin\java -classpath ../ffi/java ElgamalTest %1 %2 %3 %4 %5 %6 +popd diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/java/set-java-path.bat b/vendor/github.com/dexon-foundation/mcl/ffi/java/set-java-path.bat new file mode 100644 index 000000000..c66f81830 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/java/set-java-path.bat @@ -0,0 +1,8 @@ +@echo off +if "%JAVA_HOME%"=="" ( + set JAVA_DIR=c:/p/Java/jdk +) else ( + set JAVA_DIR=%JAVA_HOME% +) +echo JAVA_DIR=%JAVA_DIR% +rem set PATH=%PATH%;%JAVA_DIR%\bin diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/js/export-functions.py b/vendor/github.com/dexon-foundation/mcl/ffi/js/export-functions.py new file mode 100644 index 000000000..2a929564b --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/js/export-functions.py @@ -0,0 +1,73 @@ +import sys, re, argparse + +#RE_PROTOTYPE = re.compile(r'MCLBN_DLL_API\s\w\s\w\([^)]*\);') +RE_PROTOTYPE = re.compile(r'\w*\s(\w*)\s(\w*)\(([^)]*)\);') +def export_functions(args, fileNames, reToAddUnderscore): + modName = args.js + json = args.json + if not reToAddUnderscore: + reToAddUnderscore = r'(mclBn_init|setStr|getStr|[sS]erialize|setLittleEndian|setHashOf|hashAndMapTo|DecStr|HexStr|HashTo|blsSign|blsVerify|GetCurveOrder|GetFieldOrder|KeyShare|KeyRecover|blsSignatureRecover|blsInit)' + reSpecialFunctionName = re.compile(reToAddUnderscore) + if json: + print '[' + elif modName: + print 'function define_exported_' + modName + '(mod) {' + comma = '' + for fileName in fileNames: + with open(fileName, 'rb') as f: + for line in f.readlines(): + p = RE_PROTOTYPE.search(line) + if p: + ret = p.group(1) + name = p.group(2) + arg = p.group(3) + if json or modName: + retType = 'null' if ret == 'void' else 'number' + if arg == '' or arg == 'void': + paramNum = 0 + else: + paramNum = len(arg.split(',')) + if reSpecialFunctionName.search(name): + exportName = '_' + name # to wrap function + else: + exportName = name + if json: + print comma + '{' + if comma == '': + comma = ',' + print ' "name":"{0}",'.format(name) + print ' "exportName":"{0}",'.format(exportName) + print ' "ret":"{0}",'.format(retType) + print ' "args":[', + if paramNum > 0: + print '"number"' + (', "number"' * (paramNum - 1)), + print ']' + print '}' + else: + paramType = '[' + ("'number', " * paramNum) + ']' + print "{0} = mod.cwrap('{1}', '{2}', {3})".format(exportName, name, retType, paramType) + else: + print comma + "'_" + name + "'", + if comma == '': + comma = ',' + if json: + print ']' + elif modName: + print '}' + +def main(): + p = argparse.ArgumentParser('export_functions') + p.add_argument('header', type=str, nargs='+', help='headers') + p.add_argument('-js', type=str, nargs='?', help='module name') + p.add_argument('-re', type=str, nargs='?', help='regular expression file to add underscore to function name') + p.add_argument('-json', action='store_true', help='output json') + args = p.parse_args() + + reToAddUnderscore = '' + if args.re: + reToAddUnderscore = open(args.re).read().strip() + export_functions(args, args.header, reToAddUnderscore) + +if __name__ == '__main__': + main() + diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/js/pre-mcl.js b/vendor/github.com/dexon-foundation/mcl/ffi/js/pre-mcl.js new file mode 100644 index 000000000..ebc93e581 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/js/pre-mcl.js @@ -0,0 +1,5 @@ +if (typeof __dirname === 'string') { + var Module = {} + Module.wasmBinaryFile = __dirname + '/mcl_c.wasm' +} + diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/python/pairing.py b/vendor/github.com/dexon-foundation/mcl/ffi/python/pairing.py new file mode 100644 index 000000000..88b729176 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/python/pairing.py @@ -0,0 +1,80 @@ +from ctypes import * +from ctypes.wintypes import LPWSTR, LPCSTR, LPVOID + +g_lib = None + +def BN256_init(): + global g_lib + g_lib = cdll.LoadLibrary("../../bin/bn256.dll") + ret = g_lib.BN256_init() + if ret: + print "ERR BN256_init" + +class Fr(Structure): + _fields_ = [("v", c_ulonglong * 4)] + def setInt(self, v): + g_lib.BN256_Fr_setInt(self.v, v) + def setStr(self, s): + ret = g_lib.BN256_Fr_setStr(self.v, c_char_p(s)) + if ret: + print("ERR Fr:setStr") + def __str__(self): + svLen = 1024 + sv = create_string_buffer('\0' * svLen) + ret = g_lib.BN256_Fr_getStr(sv, svLen, self.v) + if ret: + print("ERR Fr:getStr") + return sv.value + def isZero(self, rhs): + return g_lib.BN256_Fr_isZero(self.v) != 0 + def isOne(self, rhs): + return g_lib.BN256_Fr_isOne(self.v) != 0 + def __eq__(self, rhs): + return g_lib.BN256_Fr_isEqual(self.v, rhs.v) != 0 + def __ne__(self, rhs): + return not(P == Q) + def __add__(self, rhs): + ret = Fr() + g_lib.BN256_Fr_add(ret.v, self.v, rhs.v) + return ret + def __sub__(self, rhs): + ret = Fr() + g_lib.BN256_Fr_sub(ret.v, self.v, rhs.v) + return ret + def __mul__(self, rhs): + ret = Fr() + g_lib.BN256_Fr_mul(ret.v, self.v, rhs.v) + return ret + def __div__(self, rhs): + ret = Fr() + g_lib.BN256_Fr_div(ret.v, self.v, rhs.v) + return ret + def __neg__(self): + ret = Fr() + g_lib.BN256_Fr_neg(ret.v, self.v) + return ret + +def Fr_add(z, x, y): + g_lib.BN256_Fr_add(z.v, x.v, y.v) + +def Fr_sub(z, x, y): + g_lib.BN256_Fr_sub(z.v, x.v, y.v) + +def Fr_mul(z, x, y): + g_lib.BN256_Fr_mul(z.v, x.v, y.v) + +def Fr_div(z, x, y): + g_lib.BN256_Fr_div(z.v, x.v, y.v) + +BN256_init() + +P = Fr() +Q = Fr() +print P == Q +print P != Q +P.setInt(5) +Q.setStr("34982034824") +print Q +R = Fr() +Fr_add(R, P, Q) +print R diff --git a/vendor/github.com/dexon-foundation/mcl/ffi/python/she.py b/vendor/github.com/dexon-foundation/mcl/ffi/python/she.py new file mode 100644 index 000000000..ab8975274 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/ffi/python/she.py @@ -0,0 +1,298 @@ +import os +import platform +from ctypes import * + +MCL_BN254 = 0 +MCLBN_FR_UNIT_SIZE = 4 +MCLBN_FP_UNIT_SIZE = 4 + +FR_SIZE = MCLBN_FR_UNIT_SIZE +G1_SIZE = MCLBN_FP_UNIT_SIZE * 3 +G2_SIZE = MCLBN_FP_UNIT_SIZE * 6 +GT_SIZE = MCLBN_FP_UNIT_SIZE * 12 + +SEC_SIZE = FR_SIZE * 2 +PUB_SIZE = G1_SIZE + G2_SIZE +G1_CIPHER_SIZE = G1_SIZE * 2 +G2_CIPHER_SIZE = G2_SIZE * 2 +GT_CIPHER_SIZE = GT_SIZE * 4 + +MCLBN_COMPILED_TIME_VAR = (MCLBN_FR_UNIT_SIZE * 10) + MCLBN_FP_UNIT_SIZE + +Buffer = c_ubyte * 1536 +lib = None + +def init(curveType=MCL_BN254): + global lib + name = platform.system() + if name == 'Linux': + libName = 'libmclshe256.so' + elif name == 'Darwin': + libName = 'libmclshe256.dylib' + elif name == 'Windows': + libName = 'mclshe256.dll' + else: + raise RuntimeError("not support yet", name) + lib = cdll.LoadLibrary(libName) + ret = lib.sheInit(MCL_BN254, MCLBN_COMPILED_TIME_VAR) + if ret != 0: + raise RuntimeError("sheInit", ret) + # custom setup for a function which returns pointer + lib.shePrecomputedPublicKeyCreate.restype = c_void_p + +def setRangeForDLP(hashSize): + ret = lib.sheSetRangeForDLP(hashSize) + if ret != 0: + raise RuntimeError("setRangeForDLP", ret) + +def setTryNum(tryNum): + ret = lib.sheSetTryNum(tryNum) + if ret != 0: + raise RuntimeError("setTryNum", ret) + +def hexStr(v): + s = "" + for x in v: + s += format(x, '02x') + return s + +class CipherTextG1(Structure): + _fields_ = [("v", c_ulonglong * G1_CIPHER_SIZE)] + def serialize(self): + buf = Buffer() + ret = lib.sheCipherTextG1Serialize(byref(buf), len(buf), byref(self.v)) + if ret == 0: + raise RuntimeError("serialize") + return buf[0:ret] + def serializeToHexStr(self): + return hexStr(self.serialize()) + +class CipherTextG2(Structure): + _fields_ = [("v", c_ulonglong * G2_CIPHER_SIZE)] + def serialize(self): + buf = Buffer() + ret = lib.sheCipherTextG2Serialize(byref(buf), len(buf), byref(self.v)) + if ret == 0: + raise RuntimeError("serialize") + return buf[0:ret] + def serializeToHexStr(self): + return hexStr(self.serialize()) + +class CipherTextGT(Structure): + _fields_ = [("v", c_ulonglong * GT_CIPHER_SIZE)] + def serialize(self): + buf = Buffer() + ret = lib.sheCipherTextGTSerialize(byref(buf), len(buf), byref(self.v)) + if ret == 0: + raise RuntimeError("serialize") + return buf[0:ret] + def serializeToHexStr(self): + return hexStr(self.serialize()) + +class PrecomputedPublicKey(Structure): + def __init__(self): + self.p = 0 + def create(self): + if not self.p: + self.p = c_void_p(lib.shePrecomputedPublicKeyCreate()) + if self.p == 0: + raise RuntimeError("PrecomputedPublicKey::create") + def destroy(self): + lib.shePrecomputedPublicKeyDestroy(self.p) + def encG1(self, m): + c = CipherTextG1() + ret = lib.shePrecomputedPublicKeyEncG1(byref(c.v), self.p, m) + if ret != 0: + raise RuntimeError("encG1", m) + return c + def encG2(self, m): + c = CipherTextG2() + ret = lib.shePrecomputedPublicKeyEncG2(byref(c.v), self.p, m) + if ret != 0: + raise RuntimeError("encG2", m) + return c + def encGT(self, m): + c = CipherTextGT() + ret = lib.shePrecomputedPublicKeyEncGT(byref(c.v), self.p, m) + if ret != 0: + raise RuntimeError("encGT", m) + return c + +class PublicKey(Structure): + _fields_ = [("v", c_ulonglong * PUB_SIZE)] + def serialize(self): + buf = Buffer() + ret = lib.shePublicKeySerialize(byref(buf), len(buf), byref(self.v)) + if ret == 0: + raise RuntimeError("serialize") + return buf[0:ret] + def serializeToHexStr(self): + return hexStr(self.serialize()) + def encG1(self, m): + c = CipherTextG1() + ret = lib.sheEncG1(byref(c.v), byref(self.v), m) + if ret != 0: + raise RuntimeError("encG1", m) + return c + def encG2(self, m): + c = CipherTextG2() + ret = lib.sheEncG2(byref(c.v), byref(self.v), m) + if ret != 0: + raise RuntimeError("encG2", m) + return c + def encGT(self, m): + c = CipherTextGT() + ret = lib.sheEncGT(byref(c.v), byref(self.v), m) + if ret != 0: + raise RuntimeError("encGT", m) + return c + def createPrecomputedPublicKey(self): + ppub = PrecomputedPublicKey() + ppub.create() + ret = lib.shePrecomputedPublicKeyInit(ppub.p, byref(self.v)) + if ret != 0: + raise RuntimeError("createPrecomputedPublicKey") + return ppub + +class SecretKey(Structure): + _fields_ = [("v", c_ulonglong * SEC_SIZE)] + def setByCSPRNG(self): + ret = lib.sheSecretKeySetByCSPRNG(byref(self.v)) + if ret != 0: + raise RuntimeError("setByCSPRNG", ret) + def serialize(self): + buf = Buffer() + ret = lib.sheSecretKeySerialize(byref(buf), len(buf), byref(self.v)) + if ret == 0: + raise RuntimeError("serialize") + return buf[0:ret] + def serializeToHexStr(self): + return hexStr(self.serialize()) + def getPulicKey(self): + pub = PublicKey() + lib.sheGetPublicKey(byref(pub.v), byref(self.v)) + return pub + def dec(self, c): + m = c_longlong() + if isinstance(c, CipherTextG1): + ret = lib.sheDecG1(byref(m), byref(self.v), byref(c.v)) + elif isinstance(c, CipherTextG2): + ret = lib.sheDecG2(byref(m), byref(self.v), byref(c.v)) + elif isinstance(c, CipherTextGT): + ret = lib.sheDecGT(byref(m), byref(self.v), byref(c.v)) + if ret != 0: + raise RuntimeError("dec") + return m.value + +def neg(c): + ret = -1 + if isinstance(c, CipherTextG1): + out = CipherTextG1() + ret = lib.sheNegG1(byref(out.v), byref(c.v)) + elif isinstance(c, CipherTextG2): + out = CipherTextG2() + ret = lib.sheNegG2(byref(out.v), byref(c.v)) + elif isinstance(c, CipherTextGT): + out = CipherTextGT() + ret = lib.sheNegGT(byref(out.v), byref(c.v)) + if ret != 0: + raise RuntimeError("neg") + return out + +def add(cx, cy): + ret = -1 + if isinstance(cx, CipherTextG1) and isinstance(cy, CipherTextG1): + out = CipherTextG1() + ret = lib.sheAddG1(byref(out.v), byref(cx.v), byref(cy.v)) + elif isinstance(cx, CipherTextG2) and isinstance(cy, CipherTextG2): + out = CipherTextG2() + ret = lib.sheAddG2(byref(out.v), byref(cx.v), byref(cy.v)) + elif isinstance(cx, CipherTextGT) and isinstance(cy, CipherTextGT): + out = CipherTextGT() + ret = lib.sheAddGT(byref(out.v), byref(cx.v), byref(cy.v)) + if ret != 0: + raise RuntimeError("add") + return out + +def sub(cx, cy): + ret = -1 + if isinstance(cx, CipherTextG1) and isinstance(cy, CipherTextG1): + out = CipherTextG1() + ret = lib.sheSubG1(byref(out.v), byref(cx.v), byref(cy.v)) + elif isinstance(cx, CipherTextG2) and isinstance(cy, CipherTextG2): + out = CipherTextG2() + ret = lib.sheSubG2(byref(out.v), byref(cx.v), byref(cy.v)) + elif isinstance(cx, CipherTextGT) and isinstance(cy, CipherTextGT): + out = CipherTextGT() + ret = lib.sheSubGT(byref(out.v), byref(cx.v), byref(cy.v)) + if ret != 0: + raise RuntimeError("sub") + return out + +def mul(cx, cy): + ret = -1 + if isinstance(cx, CipherTextG1) and isinstance(cy, CipherTextG2): + out = CipherTextGT() + ret = lib.sheMul(byref(out.v), byref(cx.v), byref(cy.v)) + elif isinstance(cx, CipherTextG1) and isinstance(cy, int): + out = CipherTextG1() + ret = lib.sheMulG1(byref(out.v), byref(cx.v), cy) + elif isinstance(cx, CipherTextG2) and isinstance(cy, int): + out = CipherTextG2() + ret = lib.sheMulG2(byref(out.v), byref(cx.v), cy) + elif isinstance(cx, CipherTextGT) and isinstance(cy, int): + out = CipherTextGT() + ret = lib.sheMulGT(byref(out.v), byref(cx.v), cy) + if ret != 0: + raise RuntimeError("mul") + return out + +if __name__ == '__main__': + init() + sec = SecretKey() + sec.setByCSPRNG() + print("sec=", sec.serializeToHexStr()) + pub = sec.getPulicKey() + print("pub=", pub.serializeToHexStr()) + + m11 = 1 + m12 = 5 + m21 = 3 + m22 = -4 + c11 = pub.encG1(m11) + c12 = pub.encG1(m12) + # dec(enc) for G1 + if sec.dec(c11) != m11: print("err1") + + # add/sub for G1 + if sec.dec(add(c11, c12)) != m11 + m12: print("err2") + if sec.dec(sub(c11, c12)) != m11 - m12: print("err3") + + # add/sub for G2 + c21 = pub.encG2(m21) + c22 = pub.encG2(m22) + if sec.dec(c21) != m21: print("err4") + if sec.dec(add(c21, c22)) != m21 + m22: print("err5") + if sec.dec(sub(c21, c22)) != m21 - m22: print("err6") + + mt = -56 + ct = pub.encGT(mt) + if sec.dec(ct) != mt: print("err7") + + # mul G1 and G2 + if sec.dec(mul(c11, c21)) != m11 * m21: print("err8") + + # use precomputedPublicKey for performance + ppub = pub.createPrecomputedPublicKey() + c1 = ppub.encG1(m11) + if sec.dec(c1) != m11: print("err9") + + import sys + if sys.version_info.major >= 3: + import timeit + N = 100000 + print(str(timeit.timeit("pub.encG1(12)", number=N, globals=globals()) / float(N) * 1e3) + "msec") + print(str(timeit.timeit("ppub.encG1(12)", number=N, globals=globals()) / float(N) * 1e3) + "msec") + + ppub.destroy() # necessary to avoid memory leak + diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp index 23096989d..ff4a78da5 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp @@ -54,11 +54,9 @@ public: } throw cybozu::Exception("randomgenerator"); } - void read_inner(void *buf, size_t byteSize) + bool read_inner(void *buf, size_t byteSize) { - if (CryptGenRandom(prov_, static_cast<DWORD>(byteSize), static_cast<BYTE*>(buf)) == 0) { - throw cybozu::Exception("randomgenerator:read") << byteSize; - } + return CryptGenRandom(prov_, static_cast<DWORD>(byteSize), static_cast<BYTE*>(buf)) != 0; } ~RandomGenerator() { @@ -71,12 +69,15 @@ public: @note bufNum is not byte size */ template<class T> - void read(T *buf, size_t bufNum) + void read(bool *pb, T *buf, size_t bufNum) { cybozu::AutoLockCs al(cs_); const size_t byteSize = sizeof(T) * bufNum; if (byteSize > bufSize) { - read_inner(buf, byteSize); + if (!read_inner(buf, byteSize)) { + *pb = false; + return; + } } else { if (pos_ + byteSize > bufSize) { read_inner(buf_, bufSize); @@ -85,6 +86,14 @@ public: memcpy(buf, buf_ + pos_, byteSize); pos_ += byteSize; } + *pb = true; + } + template<class T> + void read(T *buf, size_t bufNum) + { + bool b; + read(&b, buf, bufNum); + if (!b) throw cybozu::Exception("RandomGenerator:read") << bufNum; } private: HCRYPTPROV prov_; @@ -107,12 +116,17 @@ private: @note bufNum is not byte size */ template<class T> - void read(T *buf, size_t bufNum) + void read(bool *pb, T *buf, size_t bufNum) { const size_t byteSize = sizeof(T) * bufNum; - if (::fread(buf, 1, (int)byteSize, fp_) != byteSize) { - throw cybozu::Exception("randomgenerator:read") << byteSize; - } + *pb = ::fread(buf, 1, (int)byteSize, fp_) == byteSize; + } + template<class T> + void read(T *buf, size_t bufNum) + { + bool b; + read(&b, buf, bufNum); + if (!b) throw cybozu::Exception("RandomGenerator:read") << bufNum; } #endif private: diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp index 97193849b..1830936f0 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp @@ -6,36 +6,124 @@ @license modified new BSD license http://opensource.org/licenses/BSD-3-Clause */ -#include <cybozu/endian.hpp> +#if !defined(CYBOZU_DONT_USE_OPENSSL) && !defined(MCL_DONT_USE_OPENSSL) + #define CYBOZU_USE_OPENSSL_SHA +#endif + #ifndef CYBOZU_DONT_USE_STRING -#include <cybozu/itoa.hpp> #include <string> #endif -#include <memory.h> -#include <assert.h> -namespace cybozu { +#ifdef CYBOZU_USE_OPENSSL_SHA +#ifdef __APPLE__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#include <openssl/sha.h> +#ifdef _MSC_VER + #include <cybozu/link_libeay32.hpp> +#endif -namespace sha2_local { +#ifdef __APPLE__ + #pragma GCC diagnostic pop +#endif -template<class T> -T min_(T x, T y) { return x < y ? x : y;; } +namespace cybozu { +class Sha256 { + SHA256_CTX ctx_; +public: + Sha256() + { + clear(); + } + void clear() + { + SHA256_Init(&ctx_); + } + void update(const void *buf, size_t bufSize) + { + SHA256_Update(&ctx_, buf, bufSize); + } + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) + { + if (mdSize < SHA256_DIGEST_LENGTH) return 0; + update(buf, bufSize); + SHA256_Final(reinterpret_cast<uint8_t*>(md), &ctx_); + return SHA256_DIGEST_LENGTH; + } #ifndef CYBOZU_DONT_USE_STRING -inline void uint32toHexStr(char *buf, const uint32_t *x, size_t n) -{ - for (size_t i = 0; i < n; i++) { - cybozu::itohex(buf + i * 8, 8, x[i], false); + void update(const std::string& buf) + { + update(buf.c_str(), buf.size()); } -} + std::string digest(const std::string& buf) + { + return digest(buf.c_str(), buf.size()); + } + std::string digest(const void *buf, size_t bufSize) + { + std::string md(SHA256_DIGEST_LENGTH, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; + } +#endif +}; -inline void uint64toHexStr(char *buf, const uint64_t *x, size_t n) -{ - for (size_t i = 0; i < n; i++) { - cybozu::itohex(buf + i * 16, 16, x[i], false); +class Sha512 { + SHA512_CTX ctx_; +public: + Sha512() + { + clear(); + } + void clear() + { + SHA512_Init(&ctx_); + } + void update(const void *buf, size_t bufSize) + { + SHA512_Update(&ctx_, buf, bufSize); + } + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) + { + if (mdSize < SHA512_DIGEST_LENGTH) return 0; + update(buf, bufSize); + SHA512_Final(reinterpret_cast<uint8_t*>(md), &ctx_); + return SHA512_DIGEST_LENGTH; + } +#ifndef CYBOZU_DONT_USE_STRING + void update(const std::string& buf) + { + update(buf.c_str(), buf.size()); + } + std::string digest(const std::string& buf) + { + return digest(buf.c_str(), buf.size()); + } + std::string digest(const void *buf, size_t bufSize) + { + std::string md(SHA512_DIGEST_LENGTH, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } -} #endif +}; + +} // cybozu + +#else + +#include <cybozu/endian.hpp> +#include <memory.h> +#include <assert.h> + +namespace cybozu { + +namespace sha2_local { + +template<class T> +T min_(T x, T y) { return x < y ? x : y;; } inline uint32_t rot32(uint32_t x, int s) { @@ -55,12 +143,64 @@ inline uint64_t rot64(uint64_t x, int s) #endif } +template<class T> +struct Common { + void term(const char *buf, size_t bufSize) + { + assert(bufSize < T::blockSize_); + T& self = static_cast<T&>(*this); + const uint64_t totalSize = self.totalSize_ + bufSize; + + uint8_t last[T::blockSize_]; + memcpy(last, buf, bufSize); + last[bufSize] = uint8_t(0x80); /* top bit = 1 */ + memset(&last[bufSize + 1], 0, T::blockSize_ - bufSize - 1); + if (bufSize >= T::blockSize_ - T::msgLenByte_) { + self.round(reinterpret_cast<const char*>(last)); + memset(last, 0, sizeof(last)); // clear stack + } + cybozu::Set64bitAsBE(&last[T::blockSize_ - 8], totalSize * 8); + self.round(reinterpret_cast<const char*>(last)); + } + void inner_update(const char *buf, size_t bufSize) + { + T& self = static_cast<T&>(*this); + if (bufSize == 0) return; + if (self.roundBufSize_ > 0) { + size_t size = sha2_local::min_(T::blockSize_ - self.roundBufSize_, bufSize); + memcpy(self.roundBuf_ + self.roundBufSize_, buf, size); + self.roundBufSize_ += size; + buf += size; + bufSize -= size; + } + if (self.roundBufSize_ == T::blockSize_) { + self.round(self.roundBuf_); + self.roundBufSize_ = 0; + } + while (bufSize >= T::blockSize_) { + assert(self.roundBufSize_ == 0); + self.round(buf); + buf += T::blockSize_; + bufSize -= T::blockSize_; + } + if (bufSize > 0) { + assert(bufSize < T::blockSize_); + assert(self.roundBufSize_ == 0); + memcpy(self.roundBuf_, buf, bufSize); + self.roundBufSize_ = bufSize; + } + assert(self.roundBufSize_ < T::blockSize_); + } +}; + } // cybozu::sha2_local -class Sha256 { +class Sha256 : public sha2_local::Common<Sha256> { + friend struct sha2_local::Common<Sha256>; private: static const size_t blockSize_ = 64; static const size_t hSize_ = 8; + static const size_t msgLenByte_ = 8; uint64_t totalSize_; size_t roundBufSize_; char roundBuf_[blockSize_]; @@ -117,38 +257,13 @@ private: h_[5] += f; h_[6] += g; h_[7] += h; - totalSize_ += 64; - } - /* - final phase - */ - void term(const char *buf, size_t bufSize) - { - assert(bufSize < blockSize_); - const uint64_t totalSize = totalSize_ + bufSize; - - uint8_t last[blockSize_]; - memcpy(last, buf, bufSize); - memset(&last[bufSize], 0, blockSize_ - bufSize); - last[bufSize] = uint8_t(0x80); /* top bit = 1 */ - if (bufSize >= blockSize_ - 8) { - round(reinterpret_cast<const char*>(last)); - memset(last, 0, sizeof(last)); // clear stack - } - cybozu::Set32bitAsBE(&last[56], uint32_t(totalSize >> 29)); - cybozu::Set32bitAsBE(&last[60], uint32_t(totalSize * 8)); - round(reinterpret_cast<const char*>(last)); + totalSize_ += blockSize_; } public: Sha256() { clear(); } - Sha256(const void *buf, size_t bufSize) - { - clear(); - digest(buf, bufSize); - } void clear() { static const uint32_t kTbl[] = { @@ -173,43 +288,16 @@ public: h_[6] = 0x1f83d9ab; h_[7] = 0x5be0cd19; } - void update(const void *buf_, size_t bufSize) + void update(const void *buf, size_t bufSize) { - const char *buf = reinterpret_cast<const char*>(buf_); - if (bufSize == 0) return; - if (roundBufSize_ > 0) { - size_t size = sha2_local::min_(blockSize_ - roundBufSize_, bufSize); - memcpy(roundBuf_ + roundBufSize_, buf, size); - roundBufSize_ += size; - buf += size; - bufSize -= size; - } - if (roundBufSize_ == blockSize_) { - round(roundBuf_); - roundBufSize_ = 0; - } - while (bufSize >= blockSize_) { - assert(roundBufSize_ == 0); - round(buf); - buf += blockSize_; - bufSize -= blockSize_; - } - if (bufSize > 0) { - assert(bufSize < blockSize_); - assert(roundBufSize_ == 0); - memcpy(roundBuf_, buf, bufSize); - roundBufSize_ = bufSize; - } - assert(roundBufSize_ < blockSize_); + inner_update(reinterpret_cast<const char*>(buf), bufSize); } - void digest(const void *buf, size_t bufSize) + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) { + if (mdSize < outByteSize_) return 0; update(buf, bufSize); term(roundBuf_, roundBufSize_); - } - size_t get(void *out) const - { - char *p = reinterpret_cast<char*>(out); + char *p = reinterpret_cast<char*>(md); for (size_t i = 0; i < hSize_; i++) { cybozu::Set32bitAsBE(&p[i * sizeof(h_[0])], h_[i]); } @@ -220,29 +308,25 @@ public: { update(buf.c_str(), buf.size()); } - void digest(const std::string& str = "") + std::string digest(const std::string& buf) { - digest(str.c_str(), str.size()); + return digest(buf.c_str(), buf.size()); } - std::string get() const + std::string digest(const void *buf, size_t bufSize) { - char out[outByteSize_]; - get(out); - return std::string(out, sizeof(out)); - } - std::string toHexStr() const - { - char buf[outByteSize_ * 2]; - sha2_local::uint32toHexStr(buf, h_, hSize_); - return std::string(buf, sizeof(buf)); + std::string md(outByteSize_, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } #endif }; -class Sha512 { +class Sha512 : public sha2_local::Common<Sha512> { + friend struct sha2_local::Common<Sha512>; private: static const size_t blockSize_ = 128; static const size_t hSize_ = 8; + static const size_t msgLenByte_ = 16; uint64_t totalSize_; size_t roundBufSize_; char roundBuf_[blockSize_]; @@ -308,35 +392,11 @@ private: } totalSize_ += blockSize_; } - /* - final phase - */ - void term(const char *buf, size_t bufSize) - { - assert(bufSize < blockSize_); - const uint64_t totalSize = totalSize_ + bufSize; - - uint8_t last[blockSize_]; - memcpy(last, buf, bufSize); - memset(&last[bufSize], 0, blockSize_ - bufSize); - last[bufSize] = uint8_t(0x80); /* top bit = 1 */ - if (bufSize >= blockSize_ - 16) { - round(reinterpret_cast<const char*>(last)); - memset(last, 0, sizeof(last)); // clear stack - } - cybozu::Set64bitAsBE(&last[blockSize_ - 8], totalSize * 8); - round(reinterpret_cast<const char*>(last)); - } public: Sha512() { clear(); } - Sha512(const void *buf, size_t bufSize) - { - clear(); - digest(buf, bufSize); - } void clear() { static const uint64_t kTbl[] = { @@ -369,70 +429,39 @@ public: h_[6] = 0x1f83d9abfb41bd6bull; h_[7] = 0x5be0cd19137e2179ull; } - void update(const void *buf_, size_t bufSize) + void update(const void *buf, size_t bufSize) { - const char *buf = reinterpret_cast<const char*>(buf_); - if (bufSize == 0) return; - if (roundBufSize_ > 0) { - size_t size = sha2_local::min_(blockSize_ - roundBufSize_, bufSize); - memcpy(roundBuf_ + roundBufSize_, buf, size); - roundBufSize_ += size; - buf += size; - bufSize -= size; - } - if (roundBufSize_ == blockSize_) { - round(roundBuf_); - roundBufSize_ = 0; - } - while (bufSize >= blockSize_) { - assert(roundBufSize_ == 0); - round(buf); - buf += blockSize_; - bufSize -= blockSize_; - } - if (bufSize > 0) { - assert(bufSize < blockSize_); - assert(roundBufSize_ == 0); - memcpy(roundBuf_, buf, bufSize); - roundBufSize_ = bufSize; - } - assert(roundBufSize_ < blockSize_); + inner_update(reinterpret_cast<const char*>(buf), bufSize); } - void digest(const void *buf, size_t bufSize) + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) { + if (mdSize < outByteSize_) return 0; update(buf, bufSize); term(roundBuf_, roundBufSize_); - } - size_t get(void *out) const - { - char *p = reinterpret_cast<char*>(out); + char *p = reinterpret_cast<char*>(md); for (size_t i = 0; i < hSize_; i++) { cybozu::Set64bitAsBE(&p[i * sizeof(h_[0])], h_[i]); } return outByteSize_; } #ifndef CYBOZU_DONT_USE_STRING - void digest(const std::string& str = "") - { - digest(str.c_str(), str.size()); - } void update(const std::string& buf) { update(buf.c_str(), buf.size()); } - std::string get() const + std::string digest(const std::string& buf) { - char out[outByteSize_]; - get(out); - return std::string(out, sizeof(out)); + return digest(buf.c_str(), buf.size()); } - std::string toHexStr() const + std::string digest(const void *buf, size_t bufSize) { - char buf[outByteSize_ * 2]; - sha2_local::uint64toHexStr(buf, h_, hSize_); - return std::string(buf, sizeof(buf)); + std::string md(outByteSize_, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } #endif }; } // cybozu + +#endif diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp index 69edaa939..08c6a04f9 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp @@ -7,9 +7,47 @@ @author MITSUNARI Shigeo */ #include <cybozu/inttype.hpp> +#include <assert.h> namespace cybozu { +namespace xorshift_local { + +/* + U is uint32_t or uint64_t +*/ +template<class U, class Gen> +void read_local(void *p, size_t n, Gen& gen, U (Gen::*f)()) +{ + uint8_t *dst = static_cast<uint8_t*>(p); + const size_t uSize = sizeof(U); + assert(uSize == 4 || uSize == 8); + union ua { + U u; + uint8_t a[uSize]; + }; + + while (n >= uSize) { + ua ua; + ua.u = (gen.*f)(); + for (size_t i = 0; i < uSize; i++) { + dst[i] = ua.a[i]; + } + dst += uSize; + n -= uSize; + } + assert(n < uSize); + if (n > 0) { + ua ua; + ua.u = (gen.*f)(); + for (size_t i = 0; i < n; i++) { + dst[i] = ua.a[i]; + } + } +} + +} // xorshift_local + class XorShift { uint32_t x_, y_, z_, w_; public: @@ -38,25 +76,18 @@ public: return (uint64_t(a) << 32) | b; } template<class T> - void read(T *x, size_t n) - { - const size_t size = sizeof(T) * n; - uint8_t *p8 = static_cast<uint8_t*>(x); - for (size_t i = 0; i < size; i++) { - p8[i] = static_cast<uint8_t>(get32()); - } - } - void read(uint32_t *x, size_t n) + void read(bool *pb, T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get32(); - } + xorshift_local::read_local(p, n * sizeof(T), *this, &XorShift::get32); + *pb = true; } - void read(uint64_t *x, size_t n) + template<class T> + size_t read(T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get64(); - } + bool b; + read(&b, p, n); + (void)b; + return n; } }; @@ -90,25 +121,18 @@ public: return s_[1] + s0; } template<class T> - void read(T *x, size_t n) + void read(bool *pb, T *p, size_t n) { - const size_t size = sizeof(T) * n; - uint8_t *p8 = static_cast<uint8_t*>(x); - for (size_t i = 0; i < size; i++) { - p8[i] = static_cast<uint8_t>(get32()); - } + xorshift_local::read_local(p, n * sizeof(T), *this, &XorShift128Plus::get64); + *pb = true; } - void read(uint32_t *x, size_t n) - { - for (size_t i = 0; i < n; i++) { - x[i] = get32(); - } - } - void read(uint64_t *x, size_t n) + template<class T> + size_t read(T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get64(); - } + bool b; + read(&b, p, n); + (void)b; + return n; } }; @@ -147,25 +171,18 @@ public: return result; } template<class T> - void read(T *x, size_t n) + void read(bool *pb, T *p, size_t n) { - const size_t size = sizeof(T) * n; - uint8_t *p8 = static_cast<uint8_t*>(x); - for (size_t i = 0; i < size; i++) { - p8[i] = static_cast<uint8_t>(get32()); - } - } - void read(uint32_t *x, size_t n) - { - for (size_t i = 0; i < n; i++) { - x[i] = get32(); - } + xorshift_local::read_local(p, n * sizeof(T), *this, &Xoroshiro128Plus::get64); + *pb = true; } - void read(uint64_t *x, size_t n) + template<class T> + size_t read(T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get64(); - } + bool b; + read(&b, p, n); + (void)b; + return n; } }; diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp index 84c5f3765..a6d2a8fa3 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp @@ -8,6 +8,9 @@ */ #include <stdlib.h> #include <stddef.h> +#ifndef CYBOZU_DONT_USE_EXCEPTION +#include <new> +#endif namespace mcl { @@ -15,8 +18,6 @@ template<class T> class Array { T *p_; size_t n_; - Array(const Array&); - void operator=(const Array&); template<class U> void swap_(U& x, U& y) const { @@ -31,6 +32,26 @@ public: { free(p_); } +#ifndef CYBOZU_DONT_USE_EXCEPTION + Array(const Array& rhs) + : p_(0) + , n_(0) + { + if (rhs.n_ == 0) return; + p_ = (T*)malloc(sizeof(T) * rhs.n_); + if (p_ == 0) throw std::bad_alloc(); + n_ = rhs.n_; + for (size_t i = 0; i < n_; i++) { + p_[i] = rhs.p_[i]; + } + } + Array& operator=(const Array& rhs) + { + Array tmp(rhs); + tmp.swap(*this); + return *this; + } +#endif bool resize(size_t n) { if (n <= n_) { diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h index 9c78f92f1..0a31d5501 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h @@ -68,6 +68,8 @@ typedef struct mclBnFr mclBnFr; typedef struct mclBnG1 mclBnG1; typedef struct mclBnG2 mclBnG2; typedef struct mclBnGT mclBnGT; +typedef struct mclBnFp mclBnFp; +typedef struct mclBnFp2 mclBnFp2; #else @@ -87,6 +89,14 @@ typedef struct { uint64_t d[MCLBN_FP_UNIT_SIZE * 12]; } mclBnGT; +typedef struct { + uint64_t d[MCLBN_FP_UNIT_SIZE]; +} mclBnFp; + +typedef struct { + mclBnFp d[2]; +} mclBnFp2; + #endif #include <mcl/curve_type.h> @@ -102,6 +112,8 @@ enum { mclBls12_CurveFp381 = 5 }; +// return 0xABC which means A.BC +MCLBN_DLL_API int mclBn_getVersion(); /* init library @param curve [in] type of bn curve @@ -146,6 +158,10 @@ MCLBN_DLL_API int mclBn_getG1ByteSize(void); return bytes for serialized Fr */ MCLBN_DLL_API int mclBn_getFrByteSize(void); +/* + return bytes for serialized Fp +*/ +MCLBN_DLL_API int mclBn_getFpByteSize(void); /* return decimal string of the order of the curve(=the characteristic of Fr) @@ -168,6 +184,8 @@ MCLBN_DLL_API mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize b MCLBN_DLL_API mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize); MCLBN_DLL_API mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize); MCLBN_DLL_API mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize); /* serialize @@ -177,6 +195,8 @@ MCLBN_DLL_API mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mcl MCLBN_DLL_API mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x); MCLBN_DLL_API mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x); MCLBN_DLL_API mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x); +MCLBN_DLL_API mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x); +MCLBN_DLL_API mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x); /* set string @@ -190,6 +210,7 @@ MCLBN_DLL_API int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, i MCLBN_DLL_API int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode); MCLBN_DLL_API int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode); MCLBN_DLL_API int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode); +MCLBN_DLL_API int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode); /* buf is terminated by '\0' @@ -199,16 +220,29 @@ MCLBN_DLL_API mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnF MCLBN_DLL_API mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode); MCLBN_DLL_API mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode); MCLBN_DLL_API mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode); +MCLBN_DLL_API mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode); // set zero MCLBN_DLL_API void mclBnFr_clear(mclBnFr *x); +MCLBN_DLL_API void mclBnFp_clear(mclBnFp *x); +MCLBN_DLL_API void mclBnFp2_clear(mclBnFp2 *x); // set x to y MCLBN_DLL_API void mclBnFr_setInt(mclBnFr *y, mclInt x); MCLBN_DLL_API void mclBnFr_setInt32(mclBnFr *y, int x); -// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r +// x = buf & (1 << bitLen(r)) - 1 +// if (x >= r) x &= (1 << (bitLen(r) - 1)) - 1 +// always return 0 MCLBN_DLL_API int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize); + +// set (buf mod r) to x +// return 0 if bufSize <= (byte size of Fr * 2) else -1 +MCLBN_DLL_API int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize); +// set (buf mod p) to x +// return 0 if bufSize <= (byte size of Fp * 2) else -1 +MCLBN_DLL_API int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize); // return 1 if true and 0 otherwise MCLBN_DLL_API int mclBnFr_isValid(const mclBnFr *x); @@ -216,15 +250,33 @@ MCLBN_DLL_API int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y); MCLBN_DLL_API int mclBnFr_isZero(const mclBnFr *x); MCLBN_DLL_API int mclBnFr_isOne(const mclBnFr *x); +MCLBN_DLL_API int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y); +MCLBN_DLL_API int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y); + #ifndef MCL_DONT_USE_CSRPNG // return 0 if success MCLBN_DLL_API int mclBnFr_setByCSPRNG(mclBnFr *x); + +/* + set user-defined random function for setByCSPRNG + @param self [in] user-defined pointer + @param readFunc [in] user-defined function, + which writes random bufSize bytes to buf and returns bufSize if success else returns 0 + @note if self == 0 and readFunc == 0 then set default random function + @note not threadsafe +*/ +MCLBN_DLL_API void mclBn_setRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)); #endif // hash(s) and set x // return 0 if success MCLBN_DLL_API int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize); +// map x to y +// return 0 if success else -1 +MCLBN_DLL_API int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x); +MCLBN_DLL_API int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x); MCLBN_DLL_API void mclBnFr_neg(mclBnFr *y, const mclBnFr *x); MCLBN_DLL_API void mclBnFr_inv(mclBnFr *y, const mclBnFr *x); @@ -340,6 +392,7 @@ MCLBN_DLL_API void mclBn_precomputedMillerLoop2mixed(mclBnGT *f, const mclBnG1 * Lagrange interpolation recover out = y(0) by { (xVec[i], yVec[i]) } return 0 if success else -1 + @note *out = yVec[0] if k = 1 @note k >= 2, xVec[i] != 0, xVec[i] != xVec[j] for i != j */ MCLBN_DLL_API int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k); @@ -363,6 +416,13 @@ MCLBN_DLL_API int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, MCLBN_DLL_API void mclBn_verifyOrderG1(int doVerify); MCLBN_DLL_API void mclBn_verifyOrderG2(int doVerify); +/* + EXPERIMENTAL + only for curve = MCL_SECP* or MCL_NIST* + return standard base point of the current elliptic curve +*/ +MCLBN_DLL_API int mclBnG1_getBasePoint(mclBnG1 *x); + #ifdef __cplusplus } #endif diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp index 8e9a9c652..5ebe5d956 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp @@ -315,11 +315,18 @@ public: }; struct MapTo { + enum { + BNtype, + BLS12type, + STD_ECtype + }; Fp c1_; // sqrt(-3) Fp c2_; // (-1 + sqrt(-3)) / 2 mpz_class z_; mpz_class cofactor_; - bool isBN_; + int type_; + bool useNaiveMapTo_; + int legendre(bool *pb, const Fp& x) const { mpz_class xx; @@ -488,27 +495,44 @@ struct MapTo { (void)b; c2_ = (c1_ - 1) / 2; } - void init(const mpz_class& cofactor, const mpz_class &z, bool isBN, int curveType = -1) + /* + if type == STD_ECtype, then cofactor, z are not used. + */ + void init(const mpz_class& cofactor, const mpz_class &z, int curveType) { - isBN_ = isBN; - if (isBN_) { - initBN(cofactor, z, curveType); + if (0 <= curveType && curveType < MCL_EC_BEGIN) { + type_ = curveType == MCL_BLS12_381 ? BLS12type : BNtype; + } else { + type_ = STD_ECtype; + } + if (type_ == STD_ECtype) { + useNaiveMapTo_ = true; } else { + useNaiveMapTo_ = false; + } +#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 + if (type == BLS12type) useNaiveMapTo_ = true; +#endif + if (type_ == BNtype) { + initBN(cofactor, z, curveType); + } else if (type_ == BLS12type) { initBLS12(z); } } bool calcG1(G1& P, const Fp& t) const { - if (isBN_) { - if (!calcBN<G1, Fp>(P, t)) return false; - // no subgroup - } else { -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 + if (useNaiveMapTo_) { naiveMapTo<G1, Fp>(P, t); -#else + } else { if (!calcBN<G1, Fp>(P, t)) return false; -#endif + } + switch (type_) { + case BNtype: + // no subgroup + break; + case BLS12type: mulByCofactorBLS12(P, P); + break; } assert(P.isValid()); return true; @@ -518,16 +542,18 @@ struct MapTo { */ bool calcG2(G2& P, const Fp2& t) const { - if (isBN_) { - if (!calcBN<G2, Fp2>(P, t)) return false; - mulByCofactorBN(P, P); + if (useNaiveMapTo_) { + naiveMapTo<G2, Fp2>(P, t); } else { -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 - naiveMapTo<G1, Fp>(P, t); -#else if (!calcBN<G2, Fp2>(P, t)) return false; -#endif + } + switch(type_) { + case BNtype: + mulByCofactorBN(P, P); + break; + case BLS12type: mulByCofactorBLS12(P, P); + break; } assert(P.isValid()); return true; @@ -1018,6 +1044,9 @@ struct Param { bool useNAF; local::SignVec zReplTbl; + // for initG1only + G1 basePoint; + void init(bool *pb, const mcl::CurveParam& cp, fp::Mode mode) { this->cp = cp; @@ -1043,12 +1072,12 @@ struct Param { assert((p % 6) == 1); r = local::evalPoly(z, rCoff); } - Fp::init(pb, p, mode); - if (!*pb) return; Fr::init(pb, r, mode); if (!*pb) return; - Fp2::init(cp.xi_a); - Fp2 xi(cp.xi_a, 1); + Fp::init(pb, cp.xi_a, p, mode); + if (!*pb) return; + Fp2::init(); + const Fp2 xi(cp.xi_a, 1); g2 = Fp2::get_gTbl()[0]; g3 = Fp2::get_gTbl()[3]; if (cp.isMtype) { @@ -1099,14 +1128,31 @@ struct Param { } */ if (isBLS12) { - mapTo.init(0, z, false); + mapTo.init(0, z, cp.curveType); } else { - mapTo.init(2 * p - r, z, true, cp.curveType); + mapTo.init(2 * p - r, z, cp.curveType); } glv1.init(r, z, isBLS12, cp.curveType); glv2.init(r, z, isBLS12); + basePoint.clear(); *pb = true; } + void initG1only(bool *pb, const mcl::EcParam& para) + { + Fp::init(pb, para.p); + if (!*pb) return; + Fr::init(pb, para.n); + if (!*pb) return; + G1::init(pb, para.a, para.b); + if (!*pb) return; + G1::setOrder(Fr::getOp().mp); + mapTo.init(0, 0, para.curveType); + Fp x0, y0; + x0.setStr(pb, para.gx); + if (!*pb) return; + y0.setStr(pb, para.gy); + basePoint.set(pb, x0, y0); + } #ifndef CYBOZU_DONT_USE_EXCEPTION void init(const mcl::CurveParam& cp, fp::Mode mode) { @@ -1564,17 +1610,22 @@ inline void mulSparse(Fp12& z, const Fp6& x) } inline void convertFp6toFp12(Fp12& y, const Fp6& x) { - y.clear(); if (BN::param.cp.isMtype) { // (a, b, c) -> (a, c, 0, 0, b, 0) y.a.a = x.a; y.b.b = x.b; y.a.b = x.c; + y.a.c.clear(); + y.b.a.clear(); + y.b.c.clear(); } else { // (a, b, c) -> (b, 0, 0, c, a, 0) y.b.b = x.a; y.a.a = x.b; y.b.a = x.c; + y.a.b.clear(); + y.a.c.clear(); + y.b.c.clear(); } } inline void mulSparse2(Fp12& z, const Fp6& x, const Fp6& y) @@ -2190,5 +2241,21 @@ inline void initPairing(const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode = } #endif +inline void initG1only(bool *pb, const mcl::EcParam& para) +{ + local::StaticVar<>::param.initG1only(pb, para); + if (!*pb) return; + G1::setMulArrayGLV(0); + G2::setMulArrayGLV(0); + Fp12::setPowArrayGLV(0); + G1::setCompressedExpression(); + G2::setCompressedExpression(); +} + +inline const G1& getG1basePoint() +{ + return local::StaticVar<>::param.basePoint; +} + } } // mcl::bn diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h b/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h index 5957d1ae8..9e4a941a0 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h @@ -14,5 +14,22 @@ enum { MCL_BN462 = 3, MCL_BN_SNARK1 = 4, MCL_BLS12_381 = 5, - MCL_BN160 = 6 + MCL_BN160 = 6, + + /* + for only G1 + the size of curve must be less or equal to MCLBN_FP_UNIT_SIZE + */ + MCL_EC_BEGIN = 100, + MCL_SECP192K1 = MCL_EC_BEGIN, + MCL_SECP224K1 = 101, + MCL_SECP256K1 = 102, + MCL_SECP384R1 = 103, + MCL_SECP521R1 = 104, + MCL_NIST_P192 = 105, + MCL_NIST_P224 = 106, + MCL_NIST_P256 = 107, + MCL_EC_END = MCL_NIST_P256 + 1, + MCL_NIST_P384 = MCL_SECP384R1, + MCL_NIST_P521 = MCL_SECP521R1 }; diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp index 8ebf7e757..b8eb10be3 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp @@ -23,11 +23,11 @@ namespace mcl { namespace ec { enum Mode { - Jacobi, - Proj + Jacobi = 0, + Proj = 1 }; -} // mcl::ecl +} // mcl::ec /* elliptic curve @@ -423,27 +423,41 @@ public: dblNoVerifyInf(R, P); } #ifndef MCL_EC_USE_AFFINE - static inline void addJacobi(EcT& R, const EcT& P, const EcT& Q) + static inline void addJacobi(EcT& R, const EcT& P, const EcT& Q, bool isPzOne, bool isQzOne) { - const bool isQzOne = Q.z.isOne(); Fp r, U1, S1, H, H3; - Fp::sqr(r, P.z); + if (isPzOne) { + // r = 1; + } else { + Fp::sqr(r, P.z); + } if (isQzOne) { U1 = P.x; - Fp::mul(H, Q.x, r); + if (isPzOne) { + H = Q.x; + } else { + Fp::mul(H, Q.x, r); + } H -= U1; - r *= P.z; S1 = P.y; } else { Fp::sqr(S1, Q.z); Fp::mul(U1, P.x, S1); - Fp::mul(H, Q.x, r); + if (isPzOne) { + H = Q.x; + } else { + Fp::mul(H, Q.x, r); + } H -= U1; - r *= P.z; S1 *= Q.z; S1 *= P.y; } - r *= Q.y; + if (isPzOne) { + r = Q.y; + } else { + r *= P.z; + r *= Q.y; + } r -= S1; if (H.isZero()) { if (r.isZero()) { @@ -453,11 +467,13 @@ public: } return; } - if (isQzOne) { - Fp::mul(R.z, P.z, H); + if (isPzOne) { + R.z = H; } else { - Fp::mul(R.z, P.z, Q.z); - R.z *= H; + Fp::mul(R.z, P.z, H); + } + if (!isQzOne) { + R.z *= Q.z; } Fp::sqr(H3, H); // H^2 Fp::sqr(R.y, r); // r^2 @@ -471,9 +487,8 @@ public: H3 *= S1; Fp::sub(R.y, U1, H3); } - static inline void addProj(EcT& R, const EcT& P, const EcT& Q) + static inline void addProj(EcT& R, const EcT& P, const EcT& Q, bool isPzOne, bool isQzOne) { - const bool isQzOne = Q.z.isOne(); Fp r, PyQz, v, A, vv; if (isQzOne) { r = P.x; @@ -482,8 +497,13 @@ public: Fp::mul(r, P.x, Q.z); Fp::mul(PyQz, P.y, Q.z); } - Fp::mul(A, Q.y, P.z); - Fp::mul(v, Q.x, P.z); + if (isPzOne) { + A = Q.y; + v = Q.x; + } else { + Fp::mul(A, Q.y, P.z); + Fp::mul(v, Q.x, P.z); + } v -= r; if (v.isZero()) { if (A == PyQz) { @@ -501,10 +521,19 @@ public: if (isQzOne) { R.z = P.z; } else { - Fp::mul(R.z, P.z, Q.z); + if (isPzOne) { + R.z = Q.z; + } else { + Fp::mul(R.z, P.z, Q.z); + } + } + // R.z = 1 if isPzOne && isQzOne + if (isPzOne && isQzOne) { + R.z = vv; + } else { + A *= R.z; + R.z *= vv; } - A *= R.z; - R.z *= vv; A -= vv; vv *= PyQz; A -= r; @@ -515,17 +544,14 @@ public: R.y -= vv; } #endif - static inline void add(EcT& R, const EcT& P0, const EcT& Q0) - { - if (P0.isZero()) { R = Q0; return; } - if (Q0.isZero()) { R = P0; return; } - if (&P0 == &Q0) { - dblNoVerifyInf(R, P0); + static inline void add(EcT& R, const EcT& P, const EcT& Q) { + if (P.isZero()) { R = Q; return; } + if (Q.isZero()) { R = P; return; } + if (&P == &Q) { + dblNoVerifyInf(R, P); return; } #ifdef MCL_EC_USE_AFFINE - const EcT& P(P0); - const EcT& Q(Q0); Fp t; Fp::neg(t, Q.y); if (P.y == t) { R.clear(); return; } @@ -547,19 +573,14 @@ public: Fp::sub(R.y, s, P.y); R.x = x3; #else - const EcT *pP = &P0; - const EcT *pQ = &Q0; - if (pP->z.isOne()) { - fp::swap_(pP, pQ); - } - const EcT& P(*pP); - const EcT& Q(*pQ); + bool isPzOne = P.z.isOne(); + bool isQzOne = Q.z.isOne(); switch (mode_) { case ec::Jacobi: - addJacobi(R, P, Q); + addJacobi(R, P, Q, isPzOne, isQzOne); break; case ec::Proj: - addProj(R, P, Q); + addProj(R, P, Q, isPzOne, isQzOne); break; } #endif @@ -889,6 +910,10 @@ public: bool operator<=(const EcT& rhs) const { return !operator>(rhs); } static inline void mulArray(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime = false) { + if (!constTime && x.isZero()) { + z.clear(); + return; + } if (mulArrayGLV && (constTime || yn > 1)) { mulArrayGLV(z, x, y, yn, isNegative, constTime); return; @@ -983,6 +1008,7 @@ struct EcParam { const char *gy; const char *n; size_t bitSize; // bit length of p + int curveType; }; } // mcl diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp index 19b76bf55..087bf8b6c 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp @@ -7,6 +7,7 @@ http://opensource.org/licenses/BSD-3-Clause */ #include <mcl/ec.hpp> +#include <mcl/curve_type.h> namespace mcl { namespace ecparam { @@ -18,7 +19,8 @@ const struct mcl::EcParam secp160k1 = { "0x3b4c382ce37aa192a4019e763036f4f5dd4d7ebb", "0x938cf935318fdced6bc28286531733c3f03c4fee", "0x100000000000000000001b8fa16dfab9aca16b6b3", - 160 + 160, + -1 }; // p=2^160 + 7 const struct mcl::EcParam p160_1 = { @@ -29,7 +31,8 @@ const struct mcl::EcParam p160_1 = { "1", "1236612389951462151661156731535316138439983579284", "1461501637330902918203683518218126812711137002561", - 161 + 161, + -1 }; const struct mcl::EcParam secp192k1 = { "secp192k1", @@ -39,7 +42,8 @@ const struct mcl::EcParam secp192k1 = { "0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d", "0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", - 192 + 192, + MCL_SECP192K1 }; const struct mcl::EcParam secp224k1 = { "secp224k1", @@ -49,7 +53,8 @@ const struct mcl::EcParam secp224k1 = { "0xa1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c", "0x7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", "0x10000000000000000000000000001dce8d2ec6184caf0a971769fb1f7", - 224 + 224, + MCL_SECP224K1 }; const struct mcl::EcParam secp256k1 = { "secp256k1", @@ -59,7 +64,8 @@ const struct mcl::EcParam secp256k1 = { "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - 256 + 256, + MCL_SECP256K1 }; const struct mcl::EcParam secp384r1 = { "secp384r1", @@ -69,7 +75,8 @@ const struct mcl::EcParam secp384r1 = { "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", - 384 + 384, + MCL_SECP384R1 }; const struct mcl::EcParam secp521r1 = { "secp521r1", @@ -79,7 +86,8 @@ const struct mcl::EcParam secp521r1 = { "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - 521 + 521, + MCL_SECP521R1 }; const struct mcl::EcParam NIST_P192 = { "NIST_P192", @@ -89,7 +97,8 @@ const struct mcl::EcParam NIST_P192 = { "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", - 192 + 192, + MCL_NIST_P192 }; const struct mcl::EcParam NIST_P224 = { "NIST_P224", @@ -99,7 +108,8 @@ const struct mcl::EcParam NIST_P224 = { "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d", - 224 + 224, + MCL_NIST_P224 }; const struct mcl::EcParam NIST_P256 = { "NIST_P256", @@ -109,7 +119,8 @@ const struct mcl::EcParam NIST_P256 = { "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - 256 + 256, + MCL_NIST_P256 }; // same secp384r1 const struct mcl::EcParam NIST_P384 = { @@ -120,7 +131,8 @@ const struct mcl::EcParam NIST_P384 = { "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", - 384 + 384, + MCL_NIST_P384 }; // same secp521r1 const struct mcl::EcParam NIST_P521 = { @@ -131,7 +143,8 @@ const struct mcl::EcParam NIST_P521 = { "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - 521 + 521, + MCL_NIST_P521 }; } // mcl::ecparam @@ -161,4 +174,18 @@ static inline const mcl::EcParam* getEcParam(const std::string& name) } #endif +inline const mcl::EcParam* getEcParam(int curve) +{ + switch (curve) { + case MCL_SECP192K1: return &ecparam::secp192k1; + case MCL_SECP224K1: return &ecparam::secp224k1; + case MCL_SECP256K1: return &ecparam::secp256k1; + case MCL_SECP384R1: return &ecparam::secp384r1; + case MCL_NIST_P192: return &ecparam::NIST_P192; + case MCL_NIST_P224: return &ecparam::NIST_P224; + case MCL_NIST_P256: return &ecparam::NIST_P256; + default: return 0; + } +} + } // mcl diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp index 8bc3104b7..431148508 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp @@ -244,8 +244,7 @@ struct ElgamalT { input : m = 0 or 1 output : c (c1, c2), zkp */ - template<class Hash> - void encWithZkp(CipherText& c, Zkp& zkp, int m, Hash& hash, fp::RandGen rg = fp::RandGen()) const + void encWithZkp(CipherText& c, Zkp& zkp, int m, fp::RandGen rg = fp::RandGen()) const { if (m != 0 && m != 1) { throw cybozu::Exception("elgamal:PublicKey:encWithZkp") << m; @@ -272,10 +271,8 @@ struct ElgamalT { mulH(R12, r1); std::ostringstream os; os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h; - hash.update(os.str()); - const std::string digest = hash.digest(); Zn cc; - cc.setArrayMask(digest.c_str(), digest.size()); + cc.setHashOf(os.str()); zkp.c1 = cc - zkp.c0; zkp.s1 = r1 + zkp.c1 * u; } else { @@ -296,10 +293,8 @@ struct ElgamalT { Ec::sub(R12, t1, t2); std::ostringstream os; os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h; - hash.update(os.str()); - const std::string digest = hash.digest(); Zn cc; - cc.setArrayMask(digest.c_str(), digest.size()); + cc.setHashOf(os.str()); zkp.c0 = cc - zkp.c1; zkp.s0 = r0 + zkp.c0 * u; } @@ -307,8 +302,7 @@ struct ElgamalT { /* verify cipher text with ZKP */ - template<class Hash> - bool verify(const CipherText& c, const Zkp& zkp, Hash& hash) const + bool verify(const CipherText& c, const Zkp& zkp) const { Ec R01, R02, R11, R12; Ec t1, t2; @@ -327,10 +321,8 @@ struct ElgamalT { Ec::sub(R12, t1, t2); std::ostringstream os; os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h; - hash.update(os.str()); - const std::string digest = hash.digest(); Zn cc; - cc.setArrayMask(digest.c_str(), digest.size()); + cc.setHashOf(os.str()); return cc == zkp.c0 + zkp.c1; } /* diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp index 48500127e..2e69729dd 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp @@ -70,8 +70,6 @@ inline void dumpUnit(Unit x) bool isEnableJIT(); // 1st call is not threadsafe -void getRandVal(Unit *out, RandGen& rg, const Unit *in, size_t bitSize); - uint32_t sha256(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); uint32_t sha512(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); @@ -112,10 +110,14 @@ public: } printf("\n"); } - static inline void init(bool *pb, const mpz_class& _p, fp::Mode mode = fp::FP_AUTO) + /* + xi_a is used for Fp2::mul_xi(), where xi = xi_a + i and i^2 = -1 + if xi_a = 0 then asm functions for Fp2 are not generated. + */ + static inline void init(bool *pb, int xi_a, const mpz_class& p, fp::Mode mode = fp::FP_AUTO) { assert(maxBitSize <= MCL_MAX_BIT_SIZE); - *pb = op_.init(_p, maxBitSize, mode); + *pb = op_.init(p, maxBitSize, xi_a, mode); if (!*pb) return; { // set oneRep FpT& one = *reinterpret_cast<FpT*>(op_.oneRep); @@ -130,19 +132,23 @@ public: } inv(inv2_, 2); #ifdef MCL_XBYAK_DIRECT_CALL - add = (void (*)(FpT& z, const FpT& x, const FpT& y))op_.fp_addA_; + add = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_addA_); if (add == 0) add = addC; - sub = (void (*)(FpT& z, const FpT& x, const FpT& y))op_.fp_subA_; + sub = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_subA_); if (sub == 0) sub = subC; - neg = (void (*)(FpT& y, const FpT& x))op_.fp_negA_; + neg = fp::func_ptr_cast<void (*)(FpT& y, const FpT& x)>(op_.fp_negA_); if (neg == 0) neg = negC; - mul = (void (*)(FpT& z, const FpT& x, const FpT& y))op_.fp_mulA_; + mul = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_mulA_); if (mul == 0) mul = mulC; - sqr = (void (*)(FpT& y, const FpT& x))op_.fp_sqrA_; + sqr = fp::func_ptr_cast<void (*)(FpT& y, const FpT& x)>(op_.fp_sqrA_); if (sqr == 0) sqr = sqrC; #endif *pb = true; } + static inline void init(bool *pb, const mpz_class& p, fp::Mode mode = fp::FP_AUTO) + { + init(pb, 0, p, mode); + } static inline void init(bool *pb, const char *mstr, fp::Mode mode = fp::FP_AUTO) { mpz_class p; @@ -296,10 +302,13 @@ public: } cybozu::write(pb, os, buf + sizeof(buf) - len, len); } + /* + mode = Mod : set x mod p if sizeof(S) * n <= 64 else error + */ template<class S> - void setArray(bool *pb, const S *x, size_t n) + void setArray(bool *pb, const S *x, size_t n, mcl::fp::MaskMode mode = fp::NoMask) { - *pb = fp::copyAndMask(v_, x, sizeof(S) * n, op_, fp::NoMask); + *pb = fp::copyAndMask(v_, x, sizeof(S) * n, op_, mode); toMont(); } /* @@ -331,12 +340,21 @@ public: b.p = &v_[0]; } } - void setByCSPRNG(fp::RandGen rg = fp::RandGen()) + void setByCSPRNG(bool *pb, fp::RandGen rg = fp::RandGen()) { if (rg.isZero()) rg = fp::RandGen::get(); - fp::getRandVal(v_, rg, op_.p, op_.bitSize); - toMont(); + rg.read(pb, v_, op_.N * sizeof(Unit)); // byte size + if (!pb) return; + setArrayMask(v_, op_.N); + } +#ifndef CYBOZU_DONT_USE_EXCEPTION + void setByCSPRNG(fp::RandGen rg = fp::RandGen()) + { + bool b; + setByCSPRNG(&b, rg); + if (!b) throw cybozu::Exception("setByCSPRNG"); } +#endif void setRand(fp::RandGen rg = fp::RandGen()) // old api { setByCSPRNG(rg); @@ -522,17 +540,25 @@ public: } #endif #ifndef CYBOZU_DONT_USE_EXCEPTION - static inline void init(const mpz_class& _p, fp::Mode mode = fp::FP_AUTO) + static inline void init(int xi_a, const mpz_class& p, fp::Mode mode = fp::FP_AUTO) { bool b; - init(&b, _p, mode); + init(&b, xi_a, p, mode); if (!b) throw cybozu::Exception("Fp:init"); } + static inline void init(int xi_a, const std::string& mstr, fp::Mode mode = fp::FP_AUTO) + { + mpz_class p; + gmp::setStr(p, mstr); + init(xi_a, p, mode); + } + static inline void init(const mpz_class& p, fp::Mode mode = fp::FP_AUTO) + { + init(0, p, mode); + } static inline void init(const std::string& mstr, fp::Mode mode = fp::FP_AUTO) { - bool b; - init(&b, mstr.c_str(), mode); - if (!b) throw cybozu::Exception("Fp:init"); + init(0, mstr, mode); } template<class OutputStream> void save(OutputStream& os, int ioMode = IoSerialize) const @@ -562,7 +588,7 @@ public: { bool b; setMpz(&b, x); - if (!b) throw cybozu::Exception("Fp:setMpz:neg"); + if (!b) throw cybozu::Exception("Fp:setMpz"); } uint64_t getUint64() const { diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp index 63738a3f5..95722e2d5 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp @@ -121,20 +121,22 @@ public: static void (*add)(FpDblT& z, const FpDblT& x, const FpDblT& y); static void (*sub)(FpDblT& z, const FpDblT& x, const FpDblT& y); static void (*mod)(Fp& z, const FpDblT& xy); + static void (*addPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); + static void (*subPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); static void addC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_add(z.v_, x.v_, y.v_, Fp::op_.p); } static void subC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_sub(z.v_, x.v_, y.v_, Fp::op_.p); } static void modC(Fp& z, const FpDblT& xy) { Fp::op_.fpDbl_mod(z.v_, xy.v_, Fp::op_.p); } + static void addPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_addPre(z.v_, x.v_, y.v_); } + static void subPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_subPre(z.v_, x.v_, y.v_); } #else static void add(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_add(z.v_, x.v_, y.v_, Fp::op_.p); } static void sub(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_sub(z.v_, x.v_, y.v_, Fp::op_.p); } static void mod(Fp& z, const FpDblT& xy) { Fp::op_.fpDbl_mod(z.v_, xy.v_, Fp::op_.p); } + static void addPre(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_addPre(z.v_, x.v_, y.v_); } + static void subPre(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_subPre(z.v_, x.v_, y.v_); } #endif - static void addPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_addPre(z.v_, x.v_, y.v_); } - static void subPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_subPre(z.v_, x.v_, y.v_); } static void mulPreC(FpDblT& xy, const Fp& x, const Fp& y) { Fp::op_.fpDbl_mulPre(xy.v_, x.v_, y.v_); } static void sqrPreC(FpDblT& xx, const Fp& x) { Fp::op_.fpDbl_sqrPre(xx.v_, x.v_); } - static void (*addPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); - static void (*subPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); /* mul(z, x, y) = mulPre(xy, x, y) + mod(z, xy) */ @@ -149,30 +151,24 @@ public: { const mcl::fp::Op& op = Fp::getOp(); #ifdef MCL_XBYAK_DIRECT_CALL - add = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_addA_; + add = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_addA_); if (add == 0) add = addC; - sub = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_subA_; + sub = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_subA_); if (sub == 0) sub = subC; - mod = (void (*)(Fp&, const FpDblT&))op.fpDbl_modA_; + mod = fp::func_ptr_cast<void (*)(Fp&, const FpDblT&)>(op.fpDbl_modA_); if (mod == 0) mod = modC; + addPre = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_addPre); + if (addPre == 0) addPre = addPreC; + subPre = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_subPre); + if (subPre == 0) subPre = subPreC; #endif - if (op.fpDbl_addPreA_) { - addPre = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_addPreA_; - } else { - addPre = addPreC; - } - if (op.fpDbl_subPreA_) { - subPre = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_subPreA_; - } else { - subPre = subPreC; - } if (op.fpDbl_mulPreA_) { - mulPre = (void (*)(FpDblT&, const Fp&, const Fp&))op.fpDbl_mulPreA_; + mulPre = fp::func_ptr_cast<void (*)(FpDblT&, const Fp&, const Fp&)>(op.fpDbl_mulPreA_); } else { mulPre = mulPreC; } if (op.fpDbl_sqrPreA_) { - sqrPre = (void (*)(FpDblT&, const Fp&))op.fpDbl_sqrPreA_; + sqrPre = fp::func_ptr_cast<void (*)(FpDblT&, const Fp&)>(op.fpDbl_sqrPreA_); } else { sqrPre = sqrPreC; } @@ -185,9 +181,9 @@ public: template<class Fp> void (*FpDblT<Fp>::add)(FpDblT&, const FpDblT&, const FpDblT&); template<class Fp> void (*FpDblT<Fp>::sub)(FpDblT&, const FpDblT&, const FpDblT&); template<class Fp> void (*FpDblT<Fp>::mod)(Fp&, const FpDblT&); -#endif template<class Fp> void (*FpDblT<Fp>::addPre)(FpDblT&, const FpDblT&, const FpDblT&); template<class Fp> void (*FpDblT<Fp>::subPre)(FpDblT&, const FpDblT&, const FpDblT&); +#endif template<class Fp> void (*FpDblT<Fp>::mulPre)(FpDblT&, const Fp&, const Fp&); template<class Fp> void (*FpDblT<Fp>::sqrPre)(FpDblT&, const Fp&); @@ -206,7 +202,6 @@ class Fp2T : public fp::Serializable<Fp2T<_Fp>, typedef fp::Unit Unit; typedef FpDblT<Fp> FpDbl; typedef Fp2DblT<Fp> Fp2Dbl; - static uint32_t xi_a_; static const size_t gN = 5; /* g = xi^((p - 1) / 6) @@ -245,11 +240,19 @@ public: a = a_; b = b_; } +#ifdef MCL_XBYAK_DIRECT_CALL static void (*add)(Fp2T& z, const Fp2T& x, const Fp2T& y); static void (*sub)(Fp2T& z, const Fp2T& x, const Fp2T& y); static void (*neg)(Fp2T& y, const Fp2T& x); static void (*mul)(Fp2T& z, const Fp2T& x, const Fp2T& y); static void (*sqr)(Fp2T& y, const Fp2T& x); +#else + static void add(Fp2T& z, const Fp2T& x, const Fp2T& y) { addC(z, x, y); } + static void sub(Fp2T& z, const Fp2T& x, const Fp2T& y) { subC(z, x, y); } + static void neg(Fp2T& y, const Fp2T& x) { negC(y, x); } + static void mul(Fp2T& z, const Fp2T& x, const Fp2T& y) { mulC(z, x, y); } + static void sqr(Fp2T& y, const Fp2T& x) { sqrC(y, x); } +#endif static void (*mul_xi)(Fp2T& y, const Fp2T& x); static void addPre(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::addPre(z.a, x.a, y.a); Fp::addPre(z.b, x.b, y.b); } static void inv(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_inv(y.a.v_, x.a.v_); } @@ -377,51 +380,38 @@ public: } } - static uint32_t get_xi_a() { return xi_a_; } - static void init(uint32_t xi_a) + static uint32_t get_xi_a() { return Fp::getOp().xi_a; } + static void init() { // assert(Fp::maxSize <= 256); - xi_a_ = xi_a; mcl::fp::Op& op = Fp::op_; - add = (void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y))op.fp2_addA_; - if (add == 0) add = fp2_addC; - sub = (void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y))op.fp2_subA_; - if (sub == 0) sub = fp2_subC; - neg = (void (*)(Fp2T& y, const Fp2T& x))op.fp2_negA_; - if (neg == 0) neg = fp2_negC; - mul = (void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y))op.fp2_mulA_; - if (mul == 0) { - if (op.isFastMod) { - mul = fp2_mulC; - } else if (!op.isFullBit) { - if (0 && sizeof(Fp) * 8 == op.N * fp::UnitBitSize && op.fp2_mulNF) { - mul = fp2_mulNFW; - } else { - mul = fp2_mulC; - } - } else { - mul = fp2_mulC; - } - } - sqr = (void (*)(Fp2T& y, const Fp2T& x))op.fp2_sqrA_; - if (sqr == 0) sqr = fp2_sqrC; + assert(op.xi_a); + mul_xi = 0; +#ifdef MCL_XBYAK_DIRECT_CALL + add = fp::func_ptr_cast<void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y)>(op.fp2_addA_); + if (add == 0) add = addC; + sub = fp::func_ptr_cast<void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y)>(op.fp2_subA_); + if (sub == 0) sub = subC; + neg = fp::func_ptr_cast<void (*)(Fp2T& y, const Fp2T& x)>(op.fp2_negA_); + if (neg == 0) neg = negC; + mul = fp::func_ptr_cast<void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y)>(op.fp2_mulA_); + if (mul == 0) mul = mulC; + sqr = fp::func_ptr_cast<void (*)(Fp2T& y, const Fp2T& x)>(op.fp2_sqrA_); + if (sqr == 0) sqr = sqrC; + mul_xi = fp::func_ptr_cast<void (*)(Fp2T&, const Fp2T&)>(op.fp2_mul_xiA_); +#endif op.fp2_inv = fp2_invW; - if (xi_a == 1) { - /* - current fp_generator.hpp generates mul_xi for xi_a = 1 - */ - if (op.fp2_mul_xiA_) { - mul_xi = (void (*)(Fp2T&, const Fp2T&))op.fp2_mul_xiA_; + if (mul_xi == 0) { + if (op.xi_a == 1) { + mul_xi = fp2_mul_xi_1_1iC; } else { - mul_xi = fp2_mul_xi_1_1i; + mul_xi = fp2_mul_xiC; } - } else { - mul_xi = fp2_mul_xiC; } FpDblT<Fp>::init(); Fp2DblT<Fp>::init(); // call init before Fp2::pow because FpDbl is used in Fp2T - const Fp2T xi(xi_a, 1); + const Fp2T xi(op.xi_a, 1); const mpz_class& p = Fp::getOp().mp; Fp2T::pow(g[0], xi, (p - 1) / 6); // g = xi^((p-1)/6) for (size_t i = 1; i < gN; i++) { @@ -490,17 +480,17 @@ private: default Fp2T operator Fp2T = Fp[i]/(i^2 + 1) */ - static void fp2_addC(Fp2T& z, const Fp2T& x, const Fp2T& y) + static void addC(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::add(z.a, x.a, y.a); Fp::add(z.b, x.b, y.b); } - static void fp2_subC(Fp2T& z, const Fp2T& x, const Fp2T& y) + static void subC(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::sub(z.a, x.a, y.a); Fp::sub(z.b, x.b, y.b); } - static void fp2_negC(Fp2T& y, const Fp2T& x) + static void negC(Fp2T& y, const Fp2T& x) { Fp::neg(y.a, x.a); Fp::neg(y.b, x.b); @@ -531,13 +521,13 @@ private: Fp::sub(pz[1], t1, ac); pz[1] -= bd; } -#endif static void fp2_mulNFW(Fp2T& z, const Fp2T& x, const Fp2T& y) { const fp::Op& op = Fp::op_; op.fp2_mulNF((Unit*)&z, (const Unit*)&x, (const Unit*)&y, op.p); } - static void fp2_mulC(Fp2T& z, const Fp2T& x, const Fp2T& y) +#endif + static void mulC(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp2Dbl d; Fp2Dbl::mulPre(d, x, y); @@ -548,7 +538,7 @@ private: x = a + bi, i^2 = -1 y = x^2 = (a + bi)^2 = (a + b)(a - b) + 2abi */ - static void fp2_sqrC(Fp2T& y, const Fp2T& x) + static void sqrC(Fp2T& y, const Fp2T& x) { const Fp& a = x.a; const Fp& b = x.b; @@ -583,9 +573,9 @@ private: const Fp& a = x.a; const Fp& b = x.b; Fp t; - Fp::mulUnit(t, a, xi_a_); + Fp::mulUnit(t, a, Fp::getOp().xi_a); t -= b; - Fp::mulUnit(y.b, b, xi_a_); + Fp::mulUnit(y.b, b, Fp::getOp().xi_a); y.b += a; y.a = t; } @@ -593,7 +583,7 @@ private: xi = 1 + i ; xi_a = 1 y = (a + bi)xi = (a - b) + (a + b)i */ - static void fp2_mul_xi_1_1i(Fp2T& y, const Fp2T& x) + static void fp2_mul_xi_1_1iC(Fp2T& y, const Fp2T& x) { const Fp& a = x.a; const Fp& b = x.b; @@ -623,11 +613,13 @@ private: } }; +#ifdef MCL_XBYAK_DIRECT_CALL template<class Fp_> void (*Fp2T<Fp_>::add)(Fp2T& z, const Fp2T& x, const Fp2T& y); template<class Fp_> void (*Fp2T<Fp_>::sub)(Fp2T& z, const Fp2T& x, const Fp2T& y); template<class Fp_> void (*Fp2T<Fp_>::neg)(Fp2T& y, const Fp2T& x); template<class Fp_> void (*Fp2T<Fp_>::mul)(Fp2T& z, const Fp2T& x, const Fp2T& y); template<class Fp_> void (*Fp2T<Fp_>::sqr)(Fp2T& y, const Fp2T& x); +#endif template<class Fp_> void (*Fp2T<Fp_>::mul_xi)(Fp2T& y, const Fp2T& x); template<class Fp> @@ -697,7 +689,7 @@ struct Fp2DblT { { const mcl::fp::Op& op = Fp::getOp(); if (op.fp2Dbl_mulPreA_) { - mulPre = (void (*)(Fp2DblT&, const Fp2&, const Fp2&))op.fp2Dbl_mulPreA_; + mulPre = fp::func_ptr_cast<void (*)(Fp2DblT&, const Fp2&, const Fp2&)>(op.fp2Dbl_mulPreA_); } else { if (op.isFullBit) { mulPre = fp2Dbl_mulPreW<true>; @@ -706,7 +698,7 @@ struct Fp2DblT { } } if (op.fp2Dbl_sqrPreA_) { - sqrPre = (void (*)(Fp2DblT&, const Fp2&))op.fp2Dbl_sqrPreA_; + sqrPre = fp::func_ptr_cast<void (*)(Fp2DblT&, const Fp2&)>(op.fp2Dbl_sqrPreA_); } else { if (op.isFullBit) { sqrPre = fp2Dbl_sqrPreW<true>; @@ -769,11 +761,12 @@ struct Fp2DblT { template<class Fp> void (*Fp2DblT<Fp>::mulPre)(Fp2DblT&, const Fp2T<Fp>&, const Fp2T<Fp>&); template<class Fp> void (*Fp2DblT<Fp>::sqrPre)(Fp2DblT&, const Fp2T<Fp>&); -template<class Fp> uint32_t Fp2T<Fp>::xi_a_; template<class Fp> Fp2T<Fp> Fp2T<Fp>::g[Fp2T<Fp>::gN]; template<class Fp> Fp2T<Fp> Fp2T<Fp>::g2[Fp2T<Fp>::gN]; template<class Fp> Fp2T<Fp> Fp2T<Fp>::g3[Fp2T<Fp>::gN]; +template<class Fp> +struct Fp6DblT; /* Fp6T = Fp2[v] / (v^3 - xi) x = a + b v + c v^2 @@ -784,6 +777,7 @@ struct Fp6T : public fp::Serializable<Fp6T<_Fp>, typedef _Fp Fp; typedef Fp2T<Fp> Fp2; typedef Fp2DblT<Fp> Fp2Dbl; + typedef Fp6DblT<Fp> Fp6Dbl; typedef Fp BaseFp; Fp2 a, b, c; Fp6T() { } @@ -914,91 +908,7 @@ struct Fp6T : public fp::Serializable<Fp6T<_Fp>, y.b += t1; // c^2 xi + 2ab y.c -= t1; // b^2 + 2ac } - /* - x = a + bv + cv^2, y = d + ev + fv^2, v^3 = xi - xy = (ad + (bf + ce)xi) + ((ae + bd) + cf xi)v + ((af + cd) + be)v^2 - bf + ce = (b + c)(e + f) - be - cf - ae + bd = (a + b)(e + d) - ad - be - af + cd = (a + c)(d + f) - ad - cf - */ - static void mul(Fp6T& z, const Fp6T& x, const Fp6T& y) - { -//clk.begin(); - const Fp2& a = x.a; - const Fp2& b = x.b; - const Fp2& c = x.c; - const Fp2& d = y.a; - const Fp2& e = y.b; - const Fp2& f = y.c; -#if 1 - Fp2Dbl AD, BE, CF; - Fp2Dbl::mulPre(AD, a, d); - Fp2Dbl::mulPre(BE, b, e); - Fp2Dbl::mulPre(CF, c, f); - - Fp2 t1, t2, t3, t4; - Fp2::add(t1, b, c); - Fp2::add(t2, e, f); - Fp2Dbl T1; - Fp2Dbl::mulPre(T1, t1, t2); - Fp2Dbl::sub(T1, T1, BE); - Fp2Dbl::sub(T1, T1, CF); - Fp2Dbl::mul_xi(T1, T1); - - Fp2::add(t2, a, b); - Fp2::add(t3, e, d); - Fp2Dbl T2; - Fp2Dbl::mulPre(T2, t2, t3); - Fp2Dbl::sub(T2, T2, AD); - Fp2Dbl::sub(T2, T2, BE); - - Fp2::add(t3, a, c); - Fp2::add(t4, d, f); - Fp2Dbl T3; - Fp2Dbl::mulPre(T3, t3, t4); - Fp2Dbl::sub(T3, T3, AD); - Fp2Dbl::sub(T3, T3, CF); - - Fp2Dbl::add(AD, AD, T1); - Fp2Dbl::mod(z.a, AD); - Fp2Dbl::mul_xi(CF, CF); - Fp2Dbl::add(CF, CF, T2); - Fp2Dbl::mod(z.b, CF); - Fp2Dbl::add(T3, T3, BE); - Fp2Dbl::mod(z.c, T3); -#else - Fp2 ad, be, cf; - Fp2::mul(ad, a, d); - Fp2::mul(be, b, e); - Fp2::mul(cf, c, f); - - Fp2 t1, t2, t3, t4; - Fp2::add(t1, b, c); - Fp2::add(t2, e, f); - t1 *= t2; - t1 -= be; - t1 -= cf; - Fp2::mul_xi(t1, t1); - - Fp2::add(t2, a, b); - Fp2::add(t3, e, d); - t2 *= t3; - t2 -= ad; - t2 -= be; - - Fp2::add(t3, a, c); - Fp2::add(t4, d, f); - t3 *= t4; - t3 -= ad; - t3 -= cf; - - Fp2::add(z.a, ad, t1); - Fp2::mul_xi(z.b, cf); - z.b += t2; - Fp2::add(z.c, t3, be); -#endif -//clk.end(); - } + static inline void mul(Fp6T& z, const Fp6T& x, const Fp6T& y); /* x = a + bv + cv^2, v^3 = xi y = 1/x = p/q where @@ -1040,6 +950,94 @@ struct Fp6T : public fp::Serializable<Fp6T<_Fp>, } }; +template<class Fp> +struct Fp6DblT { + typedef Fp2T<Fp> Fp2; + typedef Fp6T<Fp> Fp6; + typedef Fp2DblT<Fp> Fp2Dbl; + typedef Fp6DblT<Fp> Fp6Dbl; + typedef fp::Unit Unit; + Fp2Dbl a, b, c; + static void add(Fp6Dbl& z, const Fp6Dbl& x, const Fp6Dbl& y) + { + Fp2Dbl::add(z.a, x.a, y.a); + Fp2Dbl::add(z.b, x.b, y.b); + Fp2Dbl::add(z.c, x.c, y.c); + } + static void sub(Fp6Dbl& z, const Fp6Dbl& x, const Fp6Dbl& y) + { + Fp2Dbl::sub(z.a, x.a, y.a); + Fp2Dbl::sub(z.b, x.b, y.b); + Fp2Dbl::sub(z.c, x.c, y.c); + } + /* + x = a + bv + cv^2, y = d + ev + fv^2, v^3 = xi + xy = (ad + (bf + ce)xi) + ((ae + bd) + cf xi)v + ((af + cd) + be)v^2 + bf + ce = (b + c)(e + f) - be - cf + ae + bd = (a + b)(e + d) - ad - be + af + cd = (a + c)(d + f) - ad - cf + */ + static void mulPre(Fp6DblT& z, const Fp6& x, const Fp6& y) + { +//clk.begin(); + const Fp2& a = x.a; + const Fp2& b = x.b; + const Fp2& c = x.c; + const Fp2& d = y.a; + const Fp2& e = y.b; + const Fp2& f = y.c; + Fp2Dbl& za = z.a; + Fp2Dbl& zb = z.b; + Fp2Dbl& zc = z.c; + Fp2Dbl BE; + Fp2Dbl::mulPre(za, a, d); + Fp2Dbl::mulPre(BE, b, e); + Fp2Dbl::mulPre(zb, c, f); + + Fp2 t1, t2, t3, t4; + Fp2::add(t1, b, c); + Fp2::add(t2, e, f); + Fp2Dbl T1; + Fp2Dbl::mulPre(T1, t1, t2); + Fp2Dbl::sub(T1, T1, BE); + Fp2Dbl::sub(T1, T1, zb); + Fp2Dbl::mul_xi(T1, T1); + + Fp2::add(t2, a, b); + Fp2::add(t3, e, d); + Fp2Dbl T2; + Fp2Dbl::mulPre(T2, t2, t3); + Fp2Dbl::sub(T2, T2, za); + Fp2Dbl::sub(T2, T2, BE); + + Fp2::add(t3, a, c); + Fp2::add(t4, d, f); + Fp2Dbl::mulPre(zc, t3, t4); + Fp2Dbl::sub(zc, zc, za); + Fp2Dbl::sub(zc, zc, zb); + + Fp2Dbl::add(za, za, T1); + Fp2Dbl::mul_xi(zb, zb); + Fp2Dbl::add(zb, zb, T2); + Fp2Dbl::add(zc, zc, BE); +//clk.end(); + } + static void mod(Fp6& y, const Fp6Dbl& x) + { + Fp2Dbl::mod(y.a, x.a); + Fp2Dbl::mod(y.b, x.b); + Fp2Dbl::mod(y.c, x.c); + } +}; + +template<class Fp> +inline void Fp6T<Fp>::mul(Fp6T<Fp>& z, const Fp6T<Fp>& x, const Fp6T<Fp>& y) +{ + Fp6DblT<Fp> Z; + Fp6DblT<Fp>::mulPre(Z, x, y); + Fp6DblT<Fp>::mod(z, Z); +} + /* Fp12T = Fp6[w] / (w^2 - v) x = a + b w @@ -1049,6 +1047,8 @@ struct Fp12T : public fp::Serializable<Fp12T<Fp>, fp::Operator<Fp12T<Fp> > > { typedef Fp2T<Fp> Fp2; typedef Fp6T<Fp> Fp6; + typedef Fp2DblT<Fp> Fp2Dbl; + typedef Fp6DblT<Fp> Fp6Dbl; typedef Fp BaseFp; Fp6 a, b; Fp12T() {} @@ -1115,6 +1115,14 @@ struct Fp12T : public fp::Serializable<Fp12T<Fp>, Fp2::add(z.b, x.a, y.b); Fp2::add(z.a, t, y.a); } + static void mulVadd(Fp6Dbl& z, const Fp6Dbl& x, const Fp6Dbl& y) + { + Fp2Dbl t; + Fp2Dbl::mul_xi(t, x.c); + Fp2Dbl::add(z.c, x.b, y.c); + Fp2Dbl::add(z.b, x.a, y.b); + Fp2Dbl::add(z.a, t, y.a); + } /* x = a + bw, y = c + dw, w^2 = v z = xy = (a + bw)(c + dw) = (ac + bdv) + (ad + bc)w @@ -1124,19 +1132,33 @@ struct Fp12T : public fp::Serializable<Fp12T<Fp>, */ static void mul(Fp12T& z, const Fp12T& x, const Fp12T& y) { + // 4.7Kclk -> 4.55Kclk const Fp6& a = x.a; const Fp6& b = x.b; const Fp6& c = y.a; const Fp6& d = y.b; - Fp6 t1, t2, ac, bd; + Fp6 t1, t2; Fp6::add(t1, a, b); Fp6::add(t2, c, d); +#if 1 + Fp6Dbl T, AC, BD; + Fp6Dbl::mulPre(AC, a, c); + Fp6Dbl::mulPre(BD, b, d); + mulVadd(T, BD, AC); + Fp6Dbl::mod(z.a, T); + Fp6Dbl::mulPre(T, t1, t2); // (a + b)(c + d) + Fp6Dbl::sub(T, T, AC); + Fp6Dbl::sub(T, T, BD); + Fp6Dbl::mod(z.b, T); +#else + Fp6 ac, bd; t1 *= t2; // (a + b)(c + d) Fp6::mul(ac, a, c); Fp6::mul(bd, b, d); mulVadd(z.a, bd, ac); t1 -= ac; Fp6::sub(z.b, t1, bd); +#endif } /* x = a + bw, w^2 = v diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp index 2dd71eb50..bcbd91a1e 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp @@ -450,7 +450,8 @@ inline void getRand(bool *pb, mpz_class& z, size_t bitSize, fp::RandGen rg = fp: *pb = false; return; } - rg.read(buf, n * sizeof(buf[0])); + rg.read(pb, buf, n * sizeof(buf[0])); + if (!*pb) return; uint32_t v = buf[n - 1]; if (rem == 0) { v |= 1U << 31; @@ -858,4 +859,96 @@ public: #endif }; +/* + Barrett Reduction + for non GMP version + mod of GMP is faster than Modp +*/ +struct Modp { + static const size_t unitBitSize = sizeof(mcl::fp::Unit) * 8; + mpz_class p_; + mpz_class u_; + mpz_class a_; + size_t pBitSize_; + size_t N_; + bool initU_; // Is u_ initialized? + Modp() + : pBitSize_(0) + , N_(0) + , initU_(false) + { + } + // x &= 1 << (unitBitSize * unitSize) + void shrinkSize(mpz_class &x, size_t unitSize) const + { + size_t u = gmp::getUnitSize(x); + if (u < unitSize) return; + bool b; + gmp::setArray(&b, x, gmp::getUnit(x), unitSize); + (void)b; + assert(b); + } + // p_ is set by p and compute (u_, a_) if possible + void init(const mpz_class& p) + { + p_ = p; + pBitSize_ = gmp::getBitSize(p); + N_ = (pBitSize_ + unitBitSize - 1) / unitBitSize; + initU_ = false; +#if 0 + u_ = (mpz_class(1) << (unitBitSize * 2 * N_)) / p_; +#else + /* + 1 << (unitBitSize * 2 * N_) may be overflow, + so use (1 << (unitBitSize * 2 * N_)) - 1 because u_ is same. + */ + uint8_t buf[48 * 2]; + const size_t byteSize = unitBitSize / 8 * 2 * N_; + if (byteSize > sizeof(buf)) return; + memset(buf, 0xff, byteSize); + bool b; + gmp::setArray(&b, u_, buf, byteSize); + if (!b) return; +#endif + u_ /= p_; + a_ = mpz_class(1) << (unitBitSize * (N_ + 1)); + initU_ = true; + } + void modp(mpz_class& r, const mpz_class& t) const + { + assert(p_ > 0); + const size_t tBitSize = gmp::getBitSize(t); + // use gmp::mod if init() fails or t is too large + if (tBitSize > unitBitSize * 2 * N_ || !initU_) { + gmp::mod(r, t, p_); + return; + } + if (tBitSize < pBitSize_) { + r = t; + return; + } + // mod is faster than modp if t is small + if (tBitSize <= unitBitSize * N_) { + gmp::mod(r, t, p_); + return; + } + mpz_class q; + q = t; + q >>= unitBitSize * (N_ - 1); + q *= u_; + q >>= unitBitSize * (N_ + 1); + q *= p_; + shrinkSize(q, N_ + 1); + r = t; + shrinkSize(r, N_ + 1); + r -= q; + if (r < 0) { + r += a_; + } + if (r >= p_) { + r -= p_; + } + } +}; + } // mcl diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp new file mode 100644 index 000000000..bec2466dd --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp @@ -0,0 +1,643 @@ +/* + This is an internal header + Do not include this +*/ +#define MCLBN_DLL_EXPORT +#include <mcl/bn.h> + +#if MCLBN_FP_UNIT_SIZE == 4 && MCLBN_FR_UNIT_SIZE == 4 +#include <mcl/bn256.hpp> +#elif MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 6 +#include <mcl/bn384.hpp> +#elif MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 4 +#include <mcl/bls12_381.hpp> +#elif MCLBN_FP_UNIT_SIZE == 8 && MCLBN_FR_UNIT_SIZE == 8 +#include <mcl/bn512.hpp> +#else + #error "not supported size" +#endif +#include <mcl/lagrange.hpp> +#include <mcl/ecparam.hpp> +using namespace mcl::bn; + +static Fr *cast(mclBnFr *p) { return reinterpret_cast<Fr*>(p); } +static const Fr *cast(const mclBnFr *p) { return reinterpret_cast<const Fr*>(p); } + +static G1 *cast(mclBnG1 *p) { return reinterpret_cast<G1*>(p); } +static const G1 *cast(const mclBnG1 *p) { return reinterpret_cast<const G1*>(p); } + +static G2 *cast(mclBnG2 *p) { return reinterpret_cast<G2*>(p); } +static const G2 *cast(const mclBnG2 *p) { return reinterpret_cast<const G2*>(p); } + +static Fp12 *cast(mclBnGT *p) { return reinterpret_cast<Fp12*>(p); } +static const Fp12 *cast(const mclBnGT *p) { return reinterpret_cast<const Fp12*>(p); } + +static Fp6 *cast(uint64_t *p) { return reinterpret_cast<Fp6*>(p); } +static const Fp6 *cast(const uint64_t *p) { return reinterpret_cast<const Fp6*>(p); } + +static Fp2 *cast(mclBnFp2 *p) { return reinterpret_cast<Fp2*>(p); } +static const Fp2 *cast(const mclBnFp2 *p) { return reinterpret_cast<const Fp2*>(p); } + +static Fp *cast(mclBnFp *p) { return reinterpret_cast<Fp*>(p); } +static const Fp *cast(const mclBnFp *p) { return reinterpret_cast<const Fp*>(p); } + +template<class T> +int setStr(T *x, const char *buf, mclSize bufSize, int ioMode) +{ + size_t n = cast(x)->deserialize(buf, bufSize, ioMode); + return n > 0 ? 0 : -1; +} + +#ifdef __EMSCRIPTEN__ +// use these functions forcibly +extern "C" MCLBN_DLL_API void *mclBnMalloc(size_t n) +{ + return malloc(n); +} +extern "C" MCLBN_DLL_API void mclBnFree(void *p) +{ + free(p); +} +#endif + +int mclBn_getVersion() +{ + return mcl::version; +} + +int mclBn_init(int curve, int compiledTimeVar) +{ + if (compiledTimeVar != MCLBN_COMPILED_TIME_VAR) { + return -(compiledTimeVar | (MCLBN_COMPILED_TIME_VAR * 100)); + } + if (MCL_EC_BEGIN <= curve && curve < MCL_EC_END) { + const mcl::EcParam *para = mcl::getEcParam(curve); + if (para == 0) return -2; + bool b; + initG1only(&b, *para); + return b ? 0 : -1; + } + const mcl::CurveParam& cp = mcl::getCurveParam(curve); + bool b; + initPairing(&b, cp); + return b ? 0 : -1; +} + +int mclBn_getOpUnitSize() +{ + return (int)Fp::getUnitSize() * sizeof(mcl::fp::Unit) / sizeof(uint64_t); +} + +int mclBn_getG1ByteSize() +{ + return mclBn_getFpByteSize(); +} + +int mclBn_getFrByteSize() +{ + return (int)Fr::getByteSize(); +} + +int mclBn_getFpByteSize() +{ + return (int)Fp::getByteSize(); +} + +mclSize mclBn_getCurveOrder(char *buf, mclSize maxBufSize) +{ + return Fr::getModulo(buf, maxBufSize); +} + +mclSize mclBn_getFieldOrder(char *buf, mclSize maxBufSize) +{ + return Fp::getModulo(buf, maxBufSize); +} + +//////////////////////////////////////////////// +// set zero +void mclBnFr_clear(mclBnFr *x) +{ + cast(x)->clear(); +} + +// set x to y +void mclBnFr_setInt(mclBnFr *y, mclInt x) +{ + *cast(y) = x; +} +void mclBnFr_setInt32(mclBnFr *y, int x) +{ + *cast(y) = x; +} + +int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize) +{ + cast(x)->setArrayMask((const char *)buf, bufSize); + return 0; +} +int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize) +{ + bool b; + cast(x)->setArray(&b, (const char *)buf, bufSize, mcl::fp::Mod); + return b ? 0 : -1; +} +mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} +// return 1 if true +int mclBnFr_isValid(const mclBnFr *x) +{ + return cast(x)->isValid(); +} +int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y) +{ + return *cast(x) == *cast(y); +} +int mclBnFr_isZero(const mclBnFr *x) +{ + return cast(x)->isZero(); +} +int mclBnFr_isOne(const mclBnFr *x) +{ + return cast(x)->isOne(); +} + +#ifndef MCL_DONT_USE_CSRPNG +int mclBnFr_setByCSPRNG(mclBnFr *x) +{ + bool b; + cast(x)->setByCSPRNG(&b); + return b ? 0 : -1; +} +void mclBn_setRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)) +{ + mcl::fp::RandGen::setRandFunc(self, readFunc); +} +#endif + +// hash(buf) and set x +int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize) +{ + cast(x)->setHashOf(buf, bufSize); + return 0; +} + +mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnFr *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} +mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mclBnFr *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnFr_neg(mclBnFr *y, const mclBnFr *x) +{ + Fr::neg(*cast(y), *cast(x)); +} +void mclBnFr_inv(mclBnFr *y, const mclBnFr *x) +{ + Fr::inv(*cast(y), *cast(x)); +} +void mclBnFr_sqr(mclBnFr *y, const mclBnFr *x) +{ + Fr::sqr(*cast(y), *cast(x)); +} +void mclBnFr_add(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnFr_sub(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnFr_mul(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnFr_div(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::div(*cast(z),*cast(x), *cast(y)); +} + +//////////////////////////////////////////////// +// set zero +void mclBnG1_clear(mclBnG1 *x) +{ + cast(x)->clear(); +} + +int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +// return 1 if true +int mclBnG1_isValid(const mclBnG1 *x) +{ + return cast(x)->isValid(); +} +int mclBnG1_isEqual(const mclBnG1 *x, const mclBnG1 *y) +{ + return *cast(x) == *cast(y); +} +int mclBnG1_isZero(const mclBnG1 *x) +{ + return cast(x)->isZero(); +} +int mclBnG1_isValidOrder(const mclBnG1 *x) +{ + return cast(x)->isValidOrder(); +} + +int mclBnG1_hashAndMapTo(mclBnG1 *x, const void *buf, mclSize bufSize) +{ + hashAndMapToG1(*cast(x), buf, bufSize); + return 0; +} + +mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} + +mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnG1_neg(mclBnG1 *y, const mclBnG1 *x) +{ + G1::neg(*cast(y), *cast(x)); +} +void mclBnG1_dbl(mclBnG1 *y, const mclBnG1 *x) +{ + G1::dbl(*cast(y), *cast(x)); +} +void mclBnG1_normalize(mclBnG1 *y, const mclBnG1 *x) +{ + G1::normalize(*cast(y), *cast(x)); +} +void mclBnG1_add(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y) +{ + G1::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnG1_sub(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y) +{ + G1::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnG1_mul(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y) +{ + G1::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnG1_mulCT(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y) +{ + G1::mulCT(*cast(z),*cast(x), *cast(y)); +} + +//////////////////////////////////////////////// +// set zero +void mclBnG2_clear(mclBnG2 *x) +{ + cast(x)->clear(); +} + +int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +// return 1 if true +int mclBnG2_isValid(const mclBnG2 *x) +{ + return cast(x)->isValid(); +} +int mclBnG2_isEqual(const mclBnG2 *x, const mclBnG2 *y) +{ + return *cast(x) == *cast(y); +} +int mclBnG2_isZero(const mclBnG2 *x) +{ + return cast(x)->isZero(); +} +int mclBnG2_isValidOrder(const mclBnG2 *x) +{ + return cast(x)->isValidOrder(); +} + +int mclBnG2_hashAndMapTo(mclBnG2 *x, const void *buf, mclSize bufSize) +{ + hashAndMapToG2(*cast(x), buf, bufSize); + return 0; +} + +mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} + +mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnG2_neg(mclBnG2 *y, const mclBnG2 *x) +{ + G2::neg(*cast(y), *cast(x)); +} +void mclBnG2_dbl(mclBnG2 *y, const mclBnG2 *x) +{ + G2::dbl(*cast(y), *cast(x)); +} +void mclBnG2_normalize(mclBnG2 *y, const mclBnG2 *x) +{ + G2::normalize(*cast(y), *cast(x)); +} +void mclBnG2_add(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y) +{ + G2::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnG2_sub(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y) +{ + G2::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnG2_mul(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y) +{ + G2::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnG2_mulCT(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y) +{ + G2::mulCT(*cast(z),*cast(x), *cast(y)); +} + +//////////////////////////////////////////////// +// set zero +void mclBnGT_clear(mclBnGT *x) +{ + cast(x)->clear(); +} +void mclBnGT_setInt(mclBnGT *y, mclInt x) +{ + cast(y)->clear(); + *(cast(y)->getFp0()) = x; +} +void mclBnGT_setInt32(mclBnGT *y, int x) +{ + cast(y)->clear(); + *(cast(y)->getFp0()) = x; +} + +int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +// return 1 if true +int mclBnGT_isEqual(const mclBnGT *x, const mclBnGT *y) +{ + return *cast(x) == *cast(y); +} +int mclBnGT_isZero(const mclBnGT *x) +{ + return cast(x)->isZero(); +} +int mclBnGT_isOne(const mclBnGT *x) +{ + return cast(x)->isOne(); +} + +mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} + +mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnGT_neg(mclBnGT *y, const mclBnGT *x) +{ + Fp12::neg(*cast(y), *cast(x)); +} +void mclBnGT_inv(mclBnGT *y, const mclBnGT *x) +{ + Fp12::inv(*cast(y), *cast(x)); +} +void mclBnGT_sqr(mclBnGT *y, const mclBnGT *x) +{ + Fp12::sqr(*cast(y), *cast(x)); +} +void mclBnGT_add(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnGT_sub(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnGT_mul(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnGT_div(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::div(*cast(z),*cast(x), *cast(y)); +} + +void mclBnGT_pow(mclBnGT *z, const mclBnGT *x, const mclBnFr *y) +{ + Fp12::pow(*cast(z), *cast(x), *cast(y)); +} +void mclBnGT_powGeneric(mclBnGT *z, const mclBnGT *x, const mclBnFr *y) +{ + Fp12::powGeneric(*cast(z), *cast(x), *cast(y)); +} + +void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y) +{ + pairing(*cast(z), *cast(x), *cast(y)); +} +void mclBn_finalExp(mclBnGT *y, const mclBnGT *x) +{ + finalExp(*cast(y), *cast(x)); +} +void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y) +{ + millerLoop(*cast(z), *cast(x), *cast(y)); +} +int mclBn_getUint64NumToPrecompute(void) +{ + return int(BN::param.precomputedQcoeffSize * sizeof(Fp6) / sizeof(uint64_t)); +} + +void mclBn_precomputeG2(uint64_t *Qbuf, const mclBnG2 *Q) +{ + precomputeG2(cast(Qbuf), *cast(Q)); +} + +void mclBn_precomputedMillerLoop(mclBnGT *f, const mclBnG1 *P, const uint64_t *Qbuf) +{ + precomputedMillerLoop(*cast(f), *cast(P), cast(Qbuf)); +} + +void mclBn_precomputedMillerLoop2(mclBnGT *f, const mclBnG1 *P1, const uint64_t *Q1buf, const mclBnG1 *P2, const uint64_t *Q2buf) +{ + precomputedMillerLoop2(*cast(f), *cast(P1), cast(Q1buf), *cast(P2), cast(Q2buf)); +} + +void mclBn_precomputedMillerLoop2mixed(mclBnGT *f, const mclBnG1 *P1, const mclBnG2 *Q1, const mclBnG1 *P2, const uint64_t *Q2buf) +{ + precomputedMillerLoop2mixed(*cast(f), *cast(P1), *cast(Q1), *cast(P2), cast(Q2buf)); +} + +int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k) +{ + bool b; + mcl::LagrangeInterpolation(&b, *cast(out), cast(xVec), cast(yVec), k); + return b ? 0 : -1; +} +int mclBn_G1LagrangeInterpolation(mclBnG1 *out, const mclBnFr *xVec, const mclBnG1 *yVec, mclSize k) +{ + bool b; + mcl::LagrangeInterpolation(&b, *cast(out), cast(xVec), cast(yVec), k); + return b ? 0 : -1; +} +int mclBn_G2LagrangeInterpolation(mclBnG2 *out, const mclBnFr *xVec, const mclBnG2 *yVec, mclSize k) +{ + bool b; + mcl::LagrangeInterpolation(&b, *cast(out), cast(xVec), cast(yVec), k); + return b ? 0 : -1; +} +int mclBn_FrEvaluatePolynomial(mclBnFr *out, const mclBnFr *cVec, mclSize cSize, const mclBnFr *x) +{ + bool b; + mcl::evaluatePolynomial(&b, *cast(out), cast(cVec), cSize, *cast(x)); + return b ? 0 : -1; +} +int mclBn_G1EvaluatePolynomial(mclBnG1 *out, const mclBnG1 *cVec, mclSize cSize, const mclBnFr *x) +{ + bool b; + mcl::evaluatePolynomial(&b, *cast(out), cast(cVec), cSize, *cast(x)); + return b ? 0 : -1; +} +int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, mclSize cSize, const mclBnFr *x) +{ + bool b; + mcl::evaluatePolynomial(&b, *cast(out), cast(cVec), cSize, *cast(x)); + return b ? 0 : -1; +} + +void mclBn_verifyOrderG1(int doVerify) +{ + verifyOrderG1(doVerify != 0); +} + +void mclBn_verifyOrderG2(int doVerify) +{ + verifyOrderG2(doVerify != 0); +} + +mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} +int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnFp_clear(mclBnFp *x) +{ + cast(x)->clear(); +} + +int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize) +{ + cast(x)->setArrayMask((const char *)buf, bufSize); + return 0; +} + +int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize) +{ + bool b; + cast(x)->setArray(&b, (const char *)buf, bufSize, mcl::fp::Mod); + return b ? 0 : -1; +} +int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y) +{ + return *cast(x) == *cast(y); +} + +int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize) +{ + cast(x)->setHashOf(buf, bufSize); + return 0; +} + +int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x) +{ + bool b; + mapToG1(&b, *cast(y), *cast(x)); + return b ? 0 : -1; +} + +mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnFp2_clear(mclBnFp2 *x) +{ + cast(x)->clear(); +} + +int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y) +{ + return *cast(x) == *cast(y); +} + +int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x) +{ + bool b; + mapToG2(&b, *cast(y), *cast(x)); + return b ? 0 : -1; +} + +int mclBnG1_getBasePoint(mclBnG1 *x) +{ + *cast(x) = mcl::bn::getG1basePoint(); + return 0; +} + diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp index 7c0218896..18e0597ec 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp @@ -15,14 +15,19 @@ namespace mcl { template<class G, class F> void LagrangeInterpolation(bool *pb, G& out, const F *S, const G *vec, size_t k) { + if (k == 0) { + *pb = false; + return; + } + if (k == 1) { + out = vec[0]; + *pb = true; + return; + } /* delta_{i,S}(0) = prod_{j != i} S[j] / (S[j] - S[i]) = a / b where a = prod S[j], b = S[i] * prod_{j != i} (S[j] - S[i]) */ - if (k < 2) { - *pb = false; - return; - } F a = S[0]; for (size_t i = 1; i < k; i++) { a *= S[i]; @@ -58,15 +63,20 @@ void LagrangeInterpolation(bool *pb, G& out, const F *S, const G *vec, size_t k) /* out = f(x) = c[0] + c[1] * x + c[2] * x^2 + ... + c[cSize - 1] * x^(cSize - 1) - @retval 0 if succeed else -1 + @retval 0 if succeed else -1 (if cSize == 0) */ template<class G, class T> void evaluatePolynomial(bool *pb, G& out, const G *c, size_t cSize, const T& x) { - if (cSize < 2) { + if (cSize == 0) { *pb = false; return; } + if (cSize == 1) { + out = c[0]; + *pb = true; + return; + } G y = c[cSize - 1]; for (int i = (int)cSize - 2; i >= 0; i--) { G::mul(y, y, x); diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp index d108d1a55..36d37035e 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp @@ -26,6 +26,8 @@ namespace mcl { +static const int version = 0x092; /* 0xABC = A.BC */ + /* specifies available string format mode for X::setIoMode() // for Fp, Fp2, Fp6, Fp12 @@ -59,7 +61,7 @@ namespace mcl { IoArray array of Unit(fixed size = Fp::getByteSize()) IoArrayRaw - array of Unit(fixed size = Fp::getByteSize()) without Montgomery convresion + array of Unit(fixed size = Fp::getByteSize()) without Montgomery conversion // for Ec::setIoMode() IoEcAffine(default) @@ -127,6 +129,15 @@ typedef int (*int2u)(Unit*, const Unit*); typedef Unit (*u1uII)(Unit*, Unit, Unit); typedef Unit (*u3u)(Unit*, const Unit*, const Unit*); +/* + disable -Wcast-function-type + the number of arguments of some JIT functions is smaller than that of T +*/ +template<class T, class S> +T func_ptr_cast(S func) +{ + return reinterpret_cast<T>(reinterpret_cast<void*>(func)); +} struct Block { const Unit *p; // pointer to original FpT.v_ size_t n; @@ -152,7 +163,8 @@ enum PrimeMode { enum MaskMode { NoMask = 0, // throw if greater or equal SmallMask = 1, // 1-bit smaller mask if greater or equal - MaskAndMod = 2 // mask and substract if greater or equal + MaskAndMod = 2, // mask and substract if greater or equal + Mod = 3 // mod p }; struct Op { @@ -165,6 +177,7 @@ struct Op { mpz_class mp; uint32_t pmod4; mcl::SquareRoot sq; + mcl::Modp modp; Unit half[maxUnitSize]; // (p + 1) / 2 Unit oneRep[maxUnitSize]; // 1(=inv R if Montgomery) /* @@ -193,8 +206,6 @@ struct Op { void2u fp2_sqrA_; void3u fpDbl_addA_; void3u fpDbl_subA_; - void3u fpDbl_addPreA_; - void3u fpDbl_subPreA_; void3u fpDbl_mulPreA_; void2u fpDbl_sqrPreA_; void2u fpDbl_modA_; @@ -282,8 +293,6 @@ struct Op { fp2_sqrA_ = 0; fpDbl_addA_ = 0; fpDbl_subA_ = 0; - fpDbl_addPreA_ = 0; - fpDbl_subPreA_ = 0; fpDbl_mulPreA_ = 0; fpDbl_sqrPreA_ = 0; fpDbl_modA_ = 0; @@ -345,8 +354,7 @@ struct Op { */ fp_mul(y, x, R2, p); } - bool init(const mpz_class& p, size_t maxBitSize, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE); - void initFp2(int xi_a); + bool init(const mpz_class& p, size_t maxBitSize, int xi_a, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE); #ifdef MCL_USE_XBYAK static FpGenerator* createFpGenerator(); static void destroyFpGenerator(FpGenerator *fg); diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp index 4bfb30b03..30502fc10 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp @@ -15,10 +15,16 @@ namespace mcl { struct RandomGeneratorJS { - void read(void *buf, size_t bufSize) + void read(bool *pb, void *buf, uint32_t byteSize) { + // cf. https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues + if (byteSize > 65536) { + *pb = false; + return; + } // use crypto.getRandomValues - EM_ASM({Module.cryptoGetRandomValues($0, $1)}, buf, bufSize); + EM_ASM({Module.cryptoGetRandomValues($0, $1)}, buf, byteSize); + *pb = true; } }; } // mcl @@ -38,28 +44,33 @@ namespace mcl { namespace fp { namespace local { template<class RG> -void readWrapper(void *self, void *buf, uint32_t bufSize) +uint32_t readWrapper(void *self, void *buf, uint32_t byteSize) { - reinterpret_cast<RG*>(self)->read((uint8_t*)buf, bufSize); + bool b; + reinterpret_cast<RG*>(self)->read(&b, (uint8_t*)buf, byteSize); + if (b) return byteSize; + return 0; } #if 0 // #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 template<> -inline void readWrapper<std::random_device>(void *self, void *buf, uint32_t bufSize) +inline uint32_t readWrapper<std::random_device>(void *self, void *buf, uint32_t byteSize) { + const uint32_t keep = byteSize; std::random_device& rg = *reinterpret_cast<std::random_device*>(self); uint8_t *p = reinterpret_cast<uint8_t*>(buf); uint32_t v; - while (bufSize >= 4) { + while (byteSize >= 4) { v = rg(); memcpy(p, &v, 4); p += 4; - bufSize -= 4; + byteSize -= 4; } - if (bufSize > 0) { + if (byteSize > 0) { v = rg(); - memcpy(p, &v, bufSize); + memcpy(p, &v, byteSize); } + return keep; } #endif } // local @@ -67,7 +78,7 @@ inline void readWrapper<std::random_device>(void *self, void *buf, uint32_t bufS wrapper of cryptographically secure pseudo random number generator */ class RandGen { - typedef void (*readFuncType)(void *self, void *buf, uint32_t bufSize); + typedef uint32_t (*readFuncType)(void *self, void *buf, uint32_t byteSize); void *self_; readFuncType readFunc_; public: @@ -87,16 +98,17 @@ public: , readFunc_(local::readWrapper<RG>) { } - void read(void *out, size_t byteSize) + void read(bool *pb, void *out, size_t byteSize) { - readFunc_(self_, out, static_cast<uint32_t>(byteSize)); + uint32_t size = readFunc_(self_, out, static_cast<uint32_t>(byteSize)); + *pb = size == byteSize; } #ifdef MCL_DONT_USE_CSPRNG bool isZero() const { return false; } /* return false to avoid copying default rg */ #else bool isZero() const { return self_ == 0 && readFunc_ == 0; } #endif - static RandGen& get() + static RandGen& getDefaultRandGen() { #ifdef MCL_DONT_USE_CSPRNG static RandGen wrg; @@ -109,14 +121,32 @@ public: #endif return wrg; } + static RandGen& get() + { + static RandGen wrg(getDefaultRandGen()); + return wrg; + } /* rg must be thread safe - rg.read(void *buf, size_t bufSize); + rg.read(void *buf, size_t byteSize); */ static void setRandGen(const RandGen& rg) { get() = rg; } + /* + set rand function + if self and readFunc are NULL then set default rand function + */ + static void setRandFunc(void *self, readFuncType readFunc) + { + if (self == 0 && readFunc == 0) { + setRandGen(getDefaultRandGen()); + } else { + RandGen rg(self, readFunc); + setRandGen(rg); + } + } }; } } // mcl::fp diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp index 32a51bb64..b087688c3 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp @@ -568,6 +568,7 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) yn = getRealSize(y, yn); if (x == y) { assert(xn == yn); + x_is_y: clearN(r, rn); if (q) { q[0] = 1; @@ -579,6 +580,7 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) /* if y > x then q = 0 and r = x */ + q_is_zero: copyN(r, x, xn); clearN(r + xn, rn - xn); if (q) clearN(q, qn); @@ -598,11 +600,61 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) clearN(r + 1, rn - 1); return; } + const size_t yTopBit = cybozu::bsr(y[yn - 1]); assert(yn >= 2); + if (xn == yn) { + const size_t xTopBit = cybozu::bsr(x[xn - 1]); + if (xTopBit < yTopBit) goto q_is_zero; + if (yTopBit == xTopBit) { + int ret = compareNM(x, xn, y, yn); + if (ret == 0) goto x_is_y; + if (ret < 0) goto q_is_zero; + if (r) { + subN(r, x, y, yn); + } + if (q) { + q[0] = 1; + clearN(q + 1, qn - 1); + } + return; + } + assert(xTopBit > yTopBit); + // fast reduction for larger than fullbit-3 size p + if (yTopBit >= sizeof(T) * 8 - 4) { + T *xx = (T*)CYBOZU_ALLOCA(sizeof(T) * xn); + T qv = 0; + if (yTopBit == sizeof(T) * 8 - 2) { + copyN(xx, x, xn); + } else { + qv = x[xn - 1] >> (yTopBit + 1); + mulu1(xx, y, yn, qv); + subN(xx, x, xx, xn); + xn = getRealSize(xx, xn); + } + for (;;) { + T ret = subN(xx, xx, y, yn); + if (ret) { + addN(xx, xx, y, yn); + break; + } + qv++; + xn = getRealSize(xx, xn); + } + if (r) { + copyN(r, xx, xn); + clearN(r + xn, rn - xn); + } + if (q) { + q[0] = qv; + clearN(q + 1, qn - 1); + } + return; + } + } /* bitwise left shift x and y to adjust MSB of y[yn - 1] = 1 */ - const size_t shift = sizeof(T) * 8 - 1 - cybozu::bsr(y[yn - 1]); + const size_t shift = sizeof(T) * 8 - 1 - yTopBit; T *xx = (T*)CYBOZU_ALLOCA(sizeof(T) * (xn + 1)); const T *yy; if (shift) { @@ -1124,8 +1176,15 @@ public: size_t unitSize = (sizeof(S) * size + sizeof(Unit) - 1) / sizeof(Unit); buf_.alloc(pb, unitSize); if (!*pb) return; - buf_[unitSize - 1] = 0; - memcpy(&buf_[0], x, sizeof(S) * size); + char *dst = (char *)&buf_[0]; + const char *src = (const char *)x; + size_t i = 0; + for (; i < sizeof(S) * size; i++) { + dst[i] = src[i]; + } + for (; i < sizeof(Unit) * unitSize; i++) { + dst[i] = 0; + } trim(unitSize); } /* @@ -1138,7 +1197,8 @@ public: size_t n = max.size(); buf_.alloc(pb, n); if (!*pb) return; - rg.read(&buf_[0], n * sizeof(buf_[0])); + rg.read(pb, &buf_[0], n * sizeof(buf_[0])); + if (!*pb) return; trim(n); *this %= max; } @@ -1231,7 +1291,8 @@ public: */ void setStr(bool *pb, const char *str, int base = 0) { - const size_t maxN = MCL_MAX_BIT_SIZE / (sizeof(MCL_SIZEOF_UNIT) * 8); + // allow twice size of MCL_MAX_BIT_SIZE because of multiplication + const size_t maxN = (MCL_MAX_BIT_SIZE * 2 + unitBitSize - 1) / unitBitSize; buf_.alloc(pb, maxN); if (!*pb) return; *pb = false; diff --git a/vendor/github.com/dexon-foundation/mcl/misc/bench.txt b/vendor/github.com/dexon-foundation/mcl/misc/bench.txt new file mode 100644 index 000000000..3e18e6b44 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/bench.txt @@ -0,0 +1,21 @@ +Core i7-7700 @ 3.6GHz + BN254 BLS12_381 +G1::mul 185.863Kclk 360.723Kclk +G1::add 812.01 clk 1.540Kclk +G1::dbl 837.24 clk 1.977Kclk +G2::mul 340.125Kclk 642.457Kclk +G2::add 2.233Kclk 4.368Kclk +G2::dbl 2.134Kclk 4.088Kclk +GT::pow 615.052Kclk 1.055Mclk +G1::setStr chk 1.546Kclk 534.376Kclk +G1::setStr 1.592Kclk 4.000Kclk +G2::setStr chk 609.195Kclk 1.402Mclk +G2::setStr 5.444Kclk 8.282Kclk +hashAndMapToG1 26.997Kclk 336.207Kclk +hashAndMapToG2 212.800Kclk 775.072Kclk +pairing 909.076Kclk 2.367Mclk +millerLoop 549.957Kclk 983.935Kclk +finalExp 375.203Kclk 1.404Mclk +precomputeG2 126.000Kclk 236.912Kclk +precomputedML 427.272Kclk 729.234Kclk + diff --git a/vendor/github.com/dexon-foundation/mcl/misc/karatsuba.cpp b/vendor/github.com/dexon-foundation/mcl/misc/karatsuba.cpp new file mode 100644 index 000000000..7c150c6e3 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/karatsuba.cpp @@ -0,0 +1,75 @@ +/* + sudo cpufreq-set -c 0 -g performance + mycl karatsuba.cpp -DMCL_USE_LLVM=1 ../lib/libmcl.a && ./a.out +*/ +#include <stdio.h> +#include <mcl/fp.hpp> +#include <cybozu/xorshift.hpp> +#include "../src/proto.hpp" +#include "../src/low_func.hpp" +#ifdef MCL_USE_LLVM +#include "../src/low_func_llvm.hpp" +#endif +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> + +typedef mcl::FpT<> Fp; + +using namespace mcl::fp; + +void dump(const Unit *x, size_t N) +{ + for (size_t i = 0; i < N; i++) { + printf("%016llx ", (long long)x[N - 1 - i]); + } + printf("\n"); +} + +void gggKara(uint64_t *z, const uint64_t *x, const uint64_t *) +{ + SqrPre<8, Gtag>::f(z, x); +} +void gggLLVM(uint64_t *z, const uint64_t *x, const uint64_t *y) +{ + MulPre<8, Ltag>::f(z, x, y); +} + +template<size_t N> +void benchKaratsuba() +{ + cybozu::XorShift rg; + printf("N=%d\n", (int)N); + Unit z[N * 2]; + rg.read(z, N); + CYBOZU_BENCH("g:mulPre ", (MulPreCore<N, Gtag>::f), z, z, z); +// CYBOZU_BENCH("g:mulKara", (MulPre<N, Gtag>::karatsuba), z, z, z); + CYBOZU_BENCH("g:sqrPre ", (SqrPreCore<N, Gtag>::f), z, z); +// CYBOZU_BENCH("g:sqrKara", (SqrPre<N, Gtag>::karatsuba), z, z); + +#ifdef MCL_USE_LLVM + CYBOZU_BENCH("l:mulPre ", (MulPreCore<N, Ltag>::f), z, z, z); + CYBOZU_BENCH("l:sqrPre ", (SqrPreCore<N, Ltag>::f), z, z); + CYBOZU_BENCH("l:mulKara", (MulPre<N, Ltag>::karatsuba), z, z, z); + CYBOZU_BENCH("l:sqrKara", (SqrPre<N, Ltag>::karatsuba), z, z); +#endif +} + +CYBOZU_TEST_AUTO(karatsuba) +{ + benchKaratsuba<4>(); + benchKaratsuba<6>(); + benchKaratsuba<8>(); +#if MCL_MAX_BIT_SIZE >= 640 + benchKaratsuba<10>(); +#endif +#if MCL_MAX_BIT_SIZE >= 768 + benchKaratsuba<12>(); +#endif +#if MCL_MAX_BIT_SIZE >= 896 + benchKaratsuba<14>(); +#endif +#if MCL_MAX_BIT_SIZE >= 1024 + benchKaratsuba<16>(); +#endif +} + diff --git a/vendor/github.com/dexon-foundation/mcl/misc/mul.cpp b/vendor/github.com/dexon-foundation/mcl/misc/mul.cpp new file mode 100644 index 000000000..146ac33a9 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/mul.cpp @@ -0,0 +1,58 @@ +/* + sudo cpufreq-set -c 0 -g performance + mycl mul.cpp -DMCL_USE_LLVM=1 ../lib/libmcl.a && ./a.out +*/ +#include <stdio.h> +#include <mcl/fp.hpp> +#include <cybozu/xorshift.hpp> +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> + +typedef mcl::FpT<> Fp; + +using namespace mcl::fp; + +void dump(const Unit *x, size_t N) +{ + for (size_t i = 0; i < N; i++) { + printf("%016llx ", (long long)x[N - 1 - i]); + } + printf("\n"); +} + +CYBOZU_TEST_AUTO(mulPre) +{ + cybozu::XorShift rg; + const char *pTbl[] = { + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", + "6701817056313037086248947066310538444882082605308124576230408038843357549886356779857393369967010764802541005796711440355753503701056323603", // 462 bit + "4562440617622195218641171605700291324893228507248559930579192517899275167208677386505912811317371399778642309573594407310688704721375437998252661319722214188251994674360264950082874192246603471", // 640 bit + "1552518092300708935148979488462502555256886017116696611139052038026050952686376886330878408828646477950487730697131073206171580044114814391444287275041181139204454976020849905550265285631598444825262999193716468750892846853816057031", // 768 bit + }; + const size_t N = 16; + const Mode modeTbl[] = { + FP_GMP_MONT, +#ifdef MCL_USE_LLVM + FP_LLVM_MONT, +#endif + }; + for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(modeTbl); j++) { + Mode mode = modeTbl[j]; + printf("%s\n", ModeToStr(mode)); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(pTbl); i++) { + const char *p = pTbl[i]; + Fp::init(p, mode); + printf("bitSize=%d\n", (int)Fp::getBitSize()); + const Op& op = Fp::getOp(); + Unit x[N], y[N * 2]; + rg.read(x, N); + rg.read(y, N * 2); + CYBOZU_BENCH("mul ", op.fp_mul, y, y, x, op.p); + CYBOZU_BENCH("sqr ", op.fp_sqr, y, y, op.p); + CYBOZU_BENCH("mulPre", op.fpDbl_mulPre, y, y, y); + CYBOZU_BENCH("sqrPre", op.fpDbl_sqrPre, y, y); + CYBOZU_BENCH("mod ", op.fpDbl_mod, y, y, op.p); + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/misc/precompute.cpp b/vendor/github.com/dexon-foundation/mcl/misc/precompute.cpp new file mode 100644 index 000000000..63cdd663b --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/precompute.cpp @@ -0,0 +1,30 @@ +#include <mcl/bn256.hpp> +#include <iostream> + +using namespace mcl::bn; + +int main() +{ + initPairing(mcl::BN254); + G2 Q; + mapToG2(Q, 1); + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Q); + puts("#if MCL_SIZEOF_UNIT == 8"); + puts("static const uint64_t QcoeffTblBN254[][6][4] = {"); + for (size_t i = 0; i < Qcoeff.size(); i++) { + const Fp6& x6 = Qcoeff[i]; + puts("\t{"); + for (size_t j = 0; j < 6; j++) { + printf("\t\t{"); + const Fp& x = x6.getFp0()[j]; + for (size_t k = 0; k < 4; k++) { + printf("0x%016llxull,", (unsigned long long)x.getUnit()[k]); + } + puts("},"); + } + puts("\t},"); + } + puts("};"); + puts("#endif"); +} diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/bench.sh b/vendor/github.com/dexon-foundation/mcl/misc/she/bench.sh new file mode 100644 index 000000000..ced87b4db --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/bench.sh @@ -0,0 +1,6 @@ +for i in 4 6 8 +do echo $i +touch test/she_test.cpp +make bin/she_test.exe CFLAGS_USER=-DMCLBN_FP_UNIT_SIZE=$i +bin/she_test.exe > misc/she/bench$i.txt +done diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/bench4.txt b/vendor/github.com/dexon-foundation/mcl/misc/she/bench4.txt new file mode 100644 index 000000000..99b2593c4 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/bench4.txt @@ -0,0 +1,99 @@ +ctest:module=log +CurveFp254BNb +ctest:module=HashTable +ctest:module=GTHashTable +ctest:module=enc_dec +ctest:module=add_sub_mul +ctest:module=add_mul_add_sub +ctest:module=innerProduct +ctest:module=io +ctest:module=bench +enc 673.772Kclk +add 8.021Kclk +mul 4.042Mclk +dec 2.194Mclk +add after mul 20.693Kclk +ctest:module=saveHash +ctest:module=hashBench +Kclk +m=000fffff decG1 1.83e+02 +m=001fffff decG1 1.83e+02 +m=003fffff decG1 1.83e+02 +m=007fffff decG1 1.90e+02 +m=00ffffff decG1 2.04e+02 +m=01ffffff decG1 2.66e+02 +m=03ffffff decG1 4.17e+02 +m=07ffffff decG1 7.15e+02 +m=0fffffff decG1 1.29e+03 +m=1fffffff decG1 2.43e+03 +m=3fffffff decG1 4.70e+03 +m=7fffffff decG1 9.28e+03 + +m=000fffff decG2 4.09e+02 +m=001fffff decG2 4.11e+02 +m=003fffff decG2 4.09e+02 +m=007fffff decG2 4.23e+02 +m=00ffffff decG2 4.48e+02 +m=01ffffff decG2 5.21e+02 +m=03ffffff decG2 7.25e+02 +m=07ffffff decG2 1.11e+03 +m=0fffffff decG2 1.87e+03 +m=1fffffff decG2 3.36e+03 +m=3fffffff decG2 6.38e+03 +m=7fffffff decG2 1.24e+04 + +m=000fffff decGT 2.20e+03 +m=001fffff decGT 2.21e+03 +m=003fffff decGT 2.20e+03 +m=007fffff decGT 2.21e+03 +m=00ffffff decGT 2.23e+03 +m=01ffffff decGT 2.28e+03 +m=03ffffff decGT 2.37e+03 +m=07ffffff decGT 2.56e+03 +m=0fffffff decGT 2.94e+03 +m=1fffffff decGT 3.78e+03 +m=3fffffff decGT 5.41e+03 +m=7fffffff decGT 8.69e+03 +large m +G1::add 7.36e-01 +G1::mul 1.92e+02 +G2::add 3.51e+00 +G2::mul 4.03e+02 +GT::mul 5.47e+00 +GT::pow 7.27e+02 +G1window 1.92e+01 +G2window 6.15e+01 +GTwindow 1.35e+02 +miller 6.69e+02 +finalExp 4.23e+02 +precomML 5.16e+02 +small m = 2097151 +G1::mul 4.52e+01 +G2::mul 1.01e+02 +GT::pow 1.33e+02 +G1window 1.55e+00 +G2window 5.02e+00 +GTwindow 1.55e+01 +encG1 2.10e+02 +encG2 4.82e+02 +encGT 2.47e+03 +encG1pre 5.31e+01 +encG2pre 1.47e+02 +encGTpre 6.01e+02 +decG1 1.84e+02 +decG2 3.96e+02 +degGT 2.20e+03 +mul 4.07e+03 +addG1 1.56e+00 +addG2 4.72e+00 +addGT 2.12e+01 +reRandG1 2.10e+02 +reRandG2 4.71e+02 +reRandGT 2.49e+03 +reRandG1pre 5.16e+01 +reRandG2pre 1.44e+02 +reRandGTpre 6.10e+02 +mulG1 9.03e+01 +mulG2 2.03e+02 +mulGT 5.34e+02 +ctest:name=she_test, module=11, total=2879, ok=2879, ng=0, exception=0 diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/bench6.txt b/vendor/github.com/dexon-foundation/mcl/misc/she/bench6.txt new file mode 100644 index 000000000..863f7129a --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/bench6.txt @@ -0,0 +1,99 @@ +ctest:module=log +CurveFp382_1 +ctest:module=HashTable +ctest:module=GTHashTable +ctest:module=enc_dec +ctest:module=add_sub_mul +ctest:module=add_mul_add_sub +ctest:module=innerProduct +ctest:module=io +ctest:module=bench +enc 2.077Mclk +add 17.694Kclk +mul 13.408Mclk +dec 5.854Mclk +add after mul 41.570Kclk +ctest:module=saveHash +ctest:module=hashBench +Kclk +m=000fffff decG1 5.34e+02 +m=001fffff decG1 5.36e+02 +m=003fffff decG1 5.34e+02 +m=007fffff decG1 5.48e+02 +m=00ffffff decG1 5.87e+02 +m=01ffffff decG1 7.11e+02 +m=03ffffff decG1 9.53e+02 +m=07ffffff decG1 1.41e+03 +m=0fffffff decG1 2.30e+03 +m=1fffffff decG1 4.11e+03 +m=3fffffff decG1 7.71e+03 +m=7fffffff decG1 1.50e+04 + +m=000fffff decG2 1.27e+03 +m=001fffff decG2 1.27e+03 +m=003fffff decG2 1.27e+03 +m=007fffff decG2 1.30e+03 +m=00ffffff decG2 1.35e+03 +m=01ffffff decG2 1.53e+03 +m=03ffffff decG2 1.88e+03 +m=07ffffff decG2 2.55e+03 +m=0fffffff decG2 3.87e+03 +m=1fffffff decG2 6.53e+03 +m=3fffffff decG2 1.18e+04 +m=7fffffff decG2 2.25e+04 + +m=000fffff decGT 6.01e+03 +m=001fffff decGT 6.03e+03 +m=003fffff decGT 6.01e+03 +m=007fffff decGT 6.04e+03 +m=00ffffff decGT 6.08e+03 +m=01ffffff decGT 6.17e+03 +m=03ffffff decGT 6.39e+03 +m=07ffffff decGT 6.71e+03 +m=0fffffff decGT 7.44e+03 +m=1fffffff decGT 8.95e+03 +m=3fffffff decGT 1.20e+04 +m=7fffffff decGT 1.80e+04 +large m +G1::add 1.48e+00 +G1::mul 5.44e+02 +G2::add 6.91e+00 +G2::mul 1.28e+03 +GT::mul 1.04e+01 +GT::pow 2.04e+03 +G1window 5.57e+01 +G2window 2.04e+02 +GTwindow 4.03e+02 +miller 2.09e+03 +finalExp 1.50e+03 +precomML 1.63e+03 +small m = 2097151 +G1::mul 8.29e+01 +G2::mul 2.05e+02 +GT::pow 2.66e+02 +G1window 3.18e+00 +G2window 1.14e+01 +GTwindow 3.19e+01 +encG1 6.01e+02 +encG2 1.49e+03 +encGT 7.66e+03 +encG1pre 1.41e+02 +encG2pre 4.71e+02 +encGTpre 1.76e+03 +decG1 5.37e+02 +decG2 1.27e+03 +degGT 6.02e+03 +mul 1.34e+04 +addG1 3.07e+00 +addG2 1.02e+01 +addGT 4.18e+01 +reRandG1 5.99e+02 +reRandG2 1.49e+03 +reRandGT 7.69e+03 +reRandG1pre 1.40e+02 +reRandG2pre 4.68e+02 +reRandGTpre 1.75e+03 +mulG1 1.65e+02 +mulG2 4.14e+02 +mulGT 1.06e+03 +ctest:name=she_test, module=11, total=2879, ok=2879, ng=0, exception=0 diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/bench8.txt b/vendor/github.com/dexon-foundation/mcl/misc/she/bench8.txt new file mode 100644 index 000000000..f8fe8fd75 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/bench8.txt @@ -0,0 +1,99 @@ +ctest:module=log +CurveFp462 +ctest:module=HashTable +ctest:module=GTHashTable +ctest:module=enc_dec +ctest:module=add_sub_mul +ctest:module=add_mul_add_sub +ctest:module=innerProduct +ctest:module=io +ctest:module=bench +enc 5.095Mclk +add 36.280Kclk +mul 30.163Mclk +dec 12.974Mclk +add after mul 76.646Kclk +ctest:module=saveHash +ctest:module=hashBench +Kclk +m=000fffff decG1 1.44e+03 +m=001fffff decG1 1.45e+03 +m=003fffff decG1 1.45e+03 +m=007fffff decG1 1.47e+03 +m=00ffffff decG1 1.54e+03 +m=01ffffff decG1 1.70e+03 +m=03ffffff decG1 2.03e+03 +m=07ffffff decG1 2.64e+03 +m=0fffffff decG1 3.88e+03 +m=1fffffff decG1 6.32e+03 +m=3fffffff decG1 1.12e+04 +m=7fffffff decG1 2.11e+04 + +m=000fffff decG2 2.99e+03 +m=001fffff decG2 3.01e+03 +m=003fffff decG2 2.99e+03 +m=007fffff decG2 3.05e+03 +m=00ffffff decG2 3.15e+03 +m=01ffffff decG2 3.41e+03 +m=03ffffff decG2 3.93e+03 +m=07ffffff decG2 4.95e+03 +m=0fffffff decG2 6.97e+03 +m=1fffffff decG2 1.10e+04 +m=3fffffff decG2 1.91e+04 +m=7fffffff decG2 3.54e+04 + +m=000fffff decGT 1.31e+04 +m=001fffff decGT 1.31e+04 +m=003fffff decGT 1.31e+04 +m=007fffff decGT 1.31e+04 +m=00ffffff decGT 1.32e+04 +m=01ffffff decGT 1.33e+04 +m=03ffffff decGT 1.36e+04 +m=07ffffff decGT 1.43e+04 +m=0fffffff decGT 1.56e+04 +m=1fffffff decGT 1.82e+04 +m=3fffffff decGT 2.34e+04 +m=7fffffff decGT 3.39e+04 +large m +G1::add 3.40e+00 +G1::mul 1.41e+03 +G2::add 1.38e+01 +G2::mul 2.93e+03 +GT::mul 1.94e+01 +GT::pow 4.30e+03 +G1window 1.59e+02 +G2window 4.89e+02 +GTwindow 8.96e+02 +miller 4.99e+03 +finalExp 3.26e+03 +precomML 3.71e+03 +small m = 2097151 +G1::mul 1.53e+02 +G2::mul 3.85e+02 +GT::pow 4.88e+02 +G1window 6.96e+00 +G2window 2.17e+01 +GTwindow 5.83e+01 +encG1 1.62e+03 +encG2 3.48e+03 +encGT 1.79e+04 +encG1pre 3.67e+02 +encG2pre 1.09e+03 +encGTpre 3.88e+03 +decG1 1.45e+03 +decG2 3.02e+03 +degGT 1.31e+04 +mul 3.02e+04 +addG1 7.08e+00 +addG2 2.03e+01 +addGT 7.68e+01 +reRandG1 1.63e+03 +reRandG2 3.48e+03 +reRandGT 1.79e+04 +reRandG1pre 3.65e+02 +reRandG2pre 1.08e+03 +reRandGTpre 3.79e+03 +mulG1 3.08e+02 +mulG2 7.65e+02 +mulGT 1.95e+03 +ctest:name=she_test, module=11, total=2879, ok=2879, ng=0, exception=0 diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/nizkp.pdf b/vendor/github.com/dexon-foundation/mcl/misc/she/nizkp.pdf Binary files differnew file mode 100644 index 000000000..7e61b5a64 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/nizkp.pdf diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/she-api-ja.md b/vendor/github.com/dexon-foundation/mcl/misc/she/she-api-ja.md new file mode 100644 index 000000000..850f11ff3 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/she-api-ja.md @@ -0,0 +1,314 @@ +# L2準åŒåž‹æš—å·ãƒ©ã‚¤ãƒ–ラリshe + +# æ¦‚è¦ +she(somewhat homomorphic encryption)ã¯ãƒšã‚¢ãƒªãƒ³ã‚°ãƒ™ãƒ¼ã‚¹ã®L2準åŒåž‹æš—å·ã¨å‘¼ã°ã‚Œã‚‹å…¬é–‹éµæš—å·ãƒ©ã‚¤ãƒ–ラリã§ã‚る。 +L2準åŒåž‹æš—å·ã¨ã¯æš—å·æ–‡åŒå£«ã®åŠ 算を複数回ã€ä¹—算を一度ã ã‘ã§ãる性質を表ã™ã€‚ + +特ã«2個ã®æ•´æ•°å€¤ãƒ™ã‚¯ãƒˆãƒ«x = (x_i), y = (y_i)ã®å„è¦ç´ ãŒæš—å·åŒ–ã•ã‚ŒãŸçŠ¶æ…‹ã§ã€ãã®2個ã®ãƒ™ã‚¯ãƒˆãƒ«ã®å†…ç©ã‚’æš—å·åŒ–ã—ãŸã¾ã¾è¨ˆç®—ã§ãる。 + +ΣEnc(x_i) Enc(y_i) = Enc(Σx_i y_i). + +# 特長 +* ペアリングベースã®æœ€æ–°ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ を実装 + * [Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and A Fast Implementation in WebAssembly : ASIA CCS2018](http://asiaccs2018.org/?page_id=632) +* C++版ã¯Windows(x64), Linux(x64, ARM64), OSX(x64)ã«å¯¾å¿œ +* JavaScript(WebAssembly 以é™JSã¨è¨˜ã™)版ã¯Chrome, Firefox, Edge, Safari(Android, iPhoneå«ã‚€), Node.jsã«å¯¾å¿œ + +# クラスã¨ä¸»ãªæ©Ÿèƒ½ + +## 主ãªã‚¯ãƒ©ã‚¹ +* 秘密éµã‚¯ãƒ©ã‚¹ SecretKey +* 公開éµã‚¯ãƒ©ã‚¹ PublicKey +* æš—å·æ–‡ã‚¯ãƒ©ã‚¹ CipherTextG1, CipherTextG2, CipherTextGT +* ゼãƒçŸ¥è˜è¨¼æ˜Žã‚¯ãƒ©ã‚¹ ZkpBin, ZkpEq, ZkpBinEq + +## æš—å·åŒ–ã¨å¾©å·æ–¹æ³• +* 秘密éµã‹ã‚‰å…¬é–‹éµã‚’作æˆã™ã‚‹ +* 公開éµã‚’用ã„ã¦æ•´æ•°ã‹ã‚‰æš—å·æ–‡ã‚’作る +* 秘密éµã‚’用ã„ã¦æš—å·æ–‡ã‚’復å·ã™ã‚‹ + +## æš—å·æ–‡åŒå£«ã®è¨ˆç®— +* åŒã˜æš—å·æ–‡ã‚¯ãƒ©ã‚¹åŒå£«ã¯åŠ 算・減算ã§ãã‚‹ +* CipherTextG1ã¨CipherTextG2ã‚’ä¹—ç®—ã™ã‚‹ã¨CipherTextGTã«ãªã‚‹ + +## 復å·ã®é‡è¦ãªæ³¨æ„点 +* ã“ã®sheã¯å¾©å·æ™‚ã«å°ã•ãªé›¢æ•£å¯¾æ•°å•é¡Œ(DLP)を解ãå¿…è¦ãŒã‚ã‚‹ +* DLPã®ãƒ†ãƒ¼ãƒ–ルサイズをsã€æš—å·æ–‡ã‚’Enc(m)ã¨ã™ã‚‹ã¨å¾©å·æ™‚é–“ã¯m/sã«æ¯”例ã™ã‚‹ +* テーブルサイズã®è¨å®šã¯`setRangeForDLP(s)`を使ㆠ+ * `m/s`ã®æœ€å¤§å€¤ã¯`setTryNum(tryNum)`ã§è¡Œã† + +## ゼãƒçŸ¥è˜è¨¼æ˜Žã‚¯ãƒ©ã‚¹ +* mã‚’æš—å·ã™ã‚‹ã¨ãã«åŒæ™‚ã«ã‚¼ãƒçŸ¥è˜è¨¼æ˜Žã‚’生æˆã™ã‚‹ +* æš—å·æ–‡ã¨ç”Ÿæˆã•ã‚ŒãŸã‚¼ãƒçŸ¥è˜è¨¼æ˜Žã¨å…¬é–‹éµã§mã«é–¢ã™ã‚‹åˆ¶ç´„æ¡ä»¶ã‚’検証ã§ãã‚‹ + +# JS版 + +## Node.jsã§ã®èªã¿è¾¼ã¿ + +``` +>npm install she-wasm +>node +>const she = require('she-wasm') +``` + +## ブラウザã§ã®èªã¿è¾¼ã¿ +[she-wasm](https://github.com/herumi/she-wasm/)ã®she.js, she\_c.js, she\_c.wasmファイルをåŒã˜ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ç½®ã„ã¦she.jsã‚’èªã¿è¾¼ã‚€ +``` +// HTML +<script src="she.js"></script> +``` + +## JS版サンプル + +``` +// システムã®åˆæœŸåŒ– +she.init().then(() => { + const sec = new she.SecretKey() + // 秘密éµã®åˆæœŸåŒ– + sec.setByCSPRNG() + + // 秘密éµsecã‹ã‚‰å…¬é–‹éµpubã‚’ä½œæˆ + const pub = sec.getPublicKey() + + const m1 = 1 + const m2 = 2 + const m3 = 3 + const m4 = -1 + + // 平文m1ã¨m2ã‚’CipherTextG1ã¨ã—ã¦æš—å·åŒ– + const c11 = pub.encG1(m1) + const c12 = pub.encG1(m2) + + // 平文m3ã¨m4ã‚’CipherTextG2ã¨ã—ã¦æš—å·åŒ– + const c21 = pub.encG2(m3) + const c22 = pub.encG2(m4) + + // c11ã¨c12, c21ã¨c22ã‚’ãã‚Œãžã‚ŒåŠ ç®— + const c1 = she.add(c11, c12) + const c2 = she.add(c21, c22) + + // c1ã¨c2ã‚’ä¹—ç®—ã™ã‚‹ã¨CipherTextGTåž‹ã«ãªã‚‹ + const ct = she.mul(c1, c2) + + // æš—å·æ–‡ctを復å·ã™ã‚‹ + console.log(`(${m1} + ${m2}) * (${m3} + ${m4}) = ${sec.dec(ct)}`) +}) +``` + +# C++版サンプル +ライブラリã®ãƒ“ルドã¯[mcl](https://github.com/herumi/mcl/#installation-requirements)ã‚’å‚ç…§ +``` +#include <mcl/she.hpp> +int main() + try +{ + using namespace mcl::she; + // システã®ãƒ åˆæœŸåŒ– + init(); + + SecretKey sec; + + // 秘密éµã®åˆæœŸåŒ– + sec.setByCSPRNG(); + + // 秘密éµsecã‹ã‚‰å…¬é–‹éµpubã‚’ä½œæˆ + PublicKey pub; + sec.getPublicKey(pub); + + int m1 = 1; + int m2 = 2; + int m3 = 3; + int m4 = -1; + + // 平文m1ã¨m2ã‚’CipherTextG1ã¨ã—ã¦æš—å·åŒ– + CipherTextG1 c11, c12; + pub.enc(c11, m1); + pub.enc(c12, m2); + + // 平文m3ã¨m4ã‚’CipherTextG2ã¨ã—ã¦æš—å·åŒ– + CipherTextG2 c21, c22; + pub.enc(c21, m3); + pub.enc(c22, m4); + + // c11ã¨c12, c21ã¨c22ã‚’ãã‚Œãžã‚ŒåŠ ç®— + CipherTextG1 c1; + CipherTextG2 c2; + CipherTextG1::add(c1, c11, c12); + CipherTextG2::add(c2, c21, c22); + + // c1ã¨c2ã‚’ä¹—ç®—ã™ã‚‹ã¨CipherTextGTåž‹ã«ãªã‚‹ + CipherTextGT ct; + CipherTextGT::mul(ct, c1, c2); + + // æš—å·æ–‡ctを復å·ã™ã‚‹ + printf("(%d + %d) * (%d + %d) = %d\n", m1, m2, m3, m4, (int)sec.dec(ct)); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} + +``` + +# クラス共通メソッド + +## シリアライズ(C++) + +* `setStr(const std::string& str, int ioMode = 0)` + * ioModeã«å¾“ã£ã¦strã§è¨å®šã™ã‚‹ + +* `getStr(std::string& str, int ioMode = 0) const` +* `std::string getStr(int ioMode = 0) const` + * ioModeã«å¾“ã£ã¦strã‚’å–å¾—ã™ã‚‹ +* `size_t serialize(void *buf, size_t maxBufSize) const` + * maxBufSize確ä¿ã•ã‚ŒãŸbufã«ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºã™ã‚‹ + * bufã«æ›¸ãè¾¼ã¾ã‚ŒãŸbyteé•·ãŒè¿”ã‚‹ + * エラーã®å ´åˆã¯0ãŒè¿”ã‚‹ +* `size_t deserialize(const void *buf, size_t bufSize)` + * bufã‹ã‚‰æœ€å¤§bufSizeã¾ã§å€¤ã‚’èªã¿è¾¼ã¿ãƒ‡ãƒªã‚·ã‚¢ãƒ©ã‚¤ã‚ºã™ã‚‹ + * èªã¿è¾¼ã¾ã‚ŒãŸbyteé•·ãŒè¿”ã‚‹ + * エラーã®å ´åˆã¯0ãŒè¿”ã‚‹ + +## シリアライズ(JS) + +* `deserialize(s)` + * Uint8Arrayåž‹sã§ãƒ‡ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚º +* `serialize()` + * シリアライズã—ã¦Uint8Arrayã®å€¤ã‚’返㙠+* `deserializeHexStr(s)` + * 16進数文å—列sã§ãƒ‡ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚º +* `serializeToHexStr()` + * 16進数文å—列sã§ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚º + +## ioMode + +* 2 ; 2進数 +* 10 ; 10進数 +* 16 ; 16進数 +* IoPrefix ; 2ã¾ãŸã¯16ã¨orã®å€¤ã‚’è¨å®šã™ã‚‹ã¨0bã¾ãŸã¯0xãŒã¤ã +* IoEcAffine ; (G1, G2ã®ã¿)アフィン座標 +* IoEcProj ; (G1, G2ã®ã¿)射影座標 +* IoSerialize ; serialize()/deserialize()ã¨åŒã˜ + +## æ³¨æ„ +* C++ã®åå‰ç©ºé–“ã¯`mcl::she` +* 以下CTã¯CipherTextG1, CipherTextG2, CipherTextGTã®ã„ãšã‚Œã‹ã‚’表㙠+* JS版ã®å¹³æ–‡ã¯32ビット整数ã®ç¯„囲ã«åˆ¶é™ã•ã‚Œã‚‹ + +## SecretKeyクラス + +* `void setByCSPRNG()`(C++) +* `void setByCSPRNG()`(JS) + * 疑似乱数ã§ç§˜å¯†éµã‚’åˆæœŸåŒ–ã™ã‚‹ + +* `int64_t dec(const CT& c) const`(C++) +* `int dec(CT c)`(JS) + * æš—å·æ–‡cを復å·ã™ã‚‹ +* `int64_t decViaGT(const CipherTextG1& c) const`(C++) +* `int64_t decViaGT(const CipherTextG2& c) const`(C++) +* `int decViaGT(CT c)`(JS) + * æš—å·æ–‡ã‚’GT経由ã§å¾©å·ã™ã‚‹ +* `bool isZero(const CT& c) const`(C++) +* `bool isZero(CT c)`(JS) + * cã®å¾©å·çµæžœãŒ0ãªã‚‰ã°true + * decã—ã¦ã‹ã‚‰0ã¨æ¯”較ã™ã‚‹ã‚ˆã‚Šã‚‚高速 + +## PublicKey, PrecomputedPublicKeyクラス +PrecomputedPublicKeyã¯PublicKeyã®é«˜é€Ÿç‰ˆ + +* `void PrecomputedPublicKey::init(const PublicKey& pub)`(C++) +* `void PrecomputedPublicKey::init(pub)`(JS) + * 公開éµpubã§PrecomputedPublicKeyã‚’åˆæœŸåŒ–ã™ã‚‹ + + +* `PrecomputedPublicKey::destroy()`(JS) + * JavaScriptã§ã¯PrecomputedPublicKeyãŒä¸è¦ã«ãªã£ãŸã‚‰ã“ã®ãƒ¡ã‚½ãƒƒãƒ‰ã‚’呼ã¶å¿…è¦ãŒã‚ã‚‹ + * ãã†ã—ãªã„ã¨ãƒ¡ãƒ¢ãƒªãƒªãƒ¼ã‚¯ã™ã‚‹ + +以下ã¯PK = PublicKey or PrecomputedPublicKey + +* `void PK::enc(CT& c, int64_t m) const`(C++) +* `CipherTextG1 PK::encG1(m)`(JS) +* `CipherTextG2 PK::encG2(m)`(JS) +* `CipherTextGT PK::encGT(m)`(JS) + * mã‚’æš—å·åŒ–ã—ã¦cã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) + +* `void PK::reRand(CT& c) const`(C++) +* `CT PK::reRand(CT c)`(JS) + * cã‚’å†ãƒ©ãƒ³ãƒ€ãƒ 化ã™ã‚‹ + * å†ãƒ©ãƒ³ãƒ€ãƒ 化ã•ã‚ŒãŸæš—å·æ–‡ã¨å…ƒã®æš—å·æ–‡ã¯åŒã˜å¹³æ–‡ã‚’æš—å·åŒ–ã—ãŸã‚‚ã®ã‹ã©ã†ã‹åˆ¤å®šã§ããªã„ + +* `void convert(CipherTextGT& cm, const CT& ca) const` +* `CipherTextGT convert(CT ca)` + * æš—å·æ–‡ca(CipherTextG1ã‹CipherTextG2)ã‚’CipherTextGTã«å¤‰æ›ã™ã‚‹ + +## CipherTextクラス + +* `void CT::add(CT& z, const CT& x const CT& y)`(C++) +* `CT she.add(CT x, CT y)`(JS) + * æš—å·æ–‡xã¨æš—å·æ–‡yを足ã—ã¦zã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) +* `void CT::sub(CT& z, const CT& x const CT& y)`(C++) +* `CT she.sub(CT x, CT y)`(JS) + * æš—å·æ–‡xã‹ã‚‰æš—å·æ–‡yを引ã„ã¦zã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) +* `void CT::neg(CT& y, const CT& x)`(C++) +* `void she.neg(CT x)`(JS) + * æš—å·æ–‡xã®ç¬¦å·å転をyã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) +* `void CT::mul(CT& z, const CT& x, int y)`(C++) +* `CT she.mulInt(CT x, int y)`(JS) + * æš—å·æ–‡xã‚’æ•´æ•°å€yã—ã¦zã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) + +* `void CipherTextGT::mul(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++) +* `CipherTextGT she.mul(CipherTextG1 x, CipherTextG2 y)`(JS) + * æš—å·æ–‡xã¨æš—å·æ–‡yを掛ã‘ã¦zã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) + +* `void CipherTextGT::mulML(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++) + * æš—å·æ–‡xã¨æš—å·æ–‡yを掛ã‘ã¦(Millerループã ã‘ã—ã¦)zã«ã‚»ãƒƒãƒˆã™ã‚‹(ã¾ãŸã¯ãã®å€¤ã‚’è¿”ã™) +* `CipherTextGT::finalExp(CipherText& , const CipherTextG1& x, const CipherTextG2& y)`(C++) + * mul(a, b) = finalExp(mulML(a, b)) + * add(mul(a, b), mul(c, d)) = finalExp(add(mulML(a, b), mulML(c, d))) + * ã™ãªã‚ã¡ç©å’Œæ¼”ç®—ã¯mulMLã—ãŸã‚‚ã®ã‚’足ã—ã¦ã‹ã‚‰æœ€å¾Œã«ä¸€åº¦finalExpã™ã‚‹ã®ãŒã‚ˆã„ + +## ゼãƒçŸ¥è˜è¨¼æ˜Žã‚¯ãƒ©ã‚¹ + +### æ¦‚è¦ +* ZkpBin æš—å·æ–‡encGi(m)(i = 1, 2, T)ã«ã¤ã„ã¦m = 0ã¾ãŸã¯1ã§ã‚ã‚‹ã“ã¨ã‚’復å·ã›ãšã«æ¤œè¨¼ã§ãã‚‹ +* ZkpEq æš—å·æ–‡encG1(m1), encG2(m2)ã«ã¤ã„ã¦m1 = m2ã§ã‚ã‚‹ã“ã¨ã‚’検証ã§ãã‚‹ +* ZkpBinEq æš—å·æ–‡encG1(m1), encG2(m2)ã«ã¤ã„ã¦m1 = m2 = 0ã¾ãŸã¯1ã§ã‚ã‚‹ã“ã¨ã‚’検証ã§ãã‚‹ + +### API +PK = PublicKey or PrecomputedPublicKey + +* `void PK::encWithZkpBin(CipherTextG1& c, Zkp& zkp, int m) const`(C++) +* `void PK::encWithZkpBin(CipherTextG2& c, Zkp& zkp, int m) const`(C++) +* `[CipherTextG1, ZkpBin] PK::encWithZkpBinG1(m)`(JS) +* `[CipherTextG2, ZkpBin] PK::encWithZkpBinG2(m)`(JS) + * m(=0 or 1)ã‚’æš—å·åŒ–ã—ã¦æš—å·æ–‡cã¨ã‚¼ãƒçŸ¥è˜è¨¼æ˜Žzkpをセットã™ã‚‹(ã¾ãŸã¯[c, zkp]ã‚’è¿”ã™) + * mãŒ0ã§ã‚‚1ã§ã‚‚ãªã‘ã‚Œã°ä¾‹å¤– +* `void PK::encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const`(C++) +* `[CipherTextG1, CipherTextG2, ZkpEq] PK::encWithZkpEq(m)`(JS) + * mã‚’æš—å·åŒ–ã—ã¦æš—å·æ–‡c1, c2ã¨ã‚¼ãƒçŸ¥è˜è¨¼æ˜Žzkpをセットã™ã‚‹(ã¾ãŸã¯[c1, c2, zkp]ã‚’è¿”ã™) +* `void PK::encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const`(C++) +* `[CipherTextG1, CipherTextG2, ZkpEqBin] PK::encWithZkpBinEq(m)`(JS) + * m(=0 or 1)ã‚’æš—å·åŒ–ã—ã¦æš—å·æ–‡c1, c2ã¨ã‚¼ãƒçŸ¥è˜è¨¼æ˜Žzkpをセットã™ã‚‹(ã¾ãŸã¯[c1, c2, zkp]ã‚’è¿”ã™) + * mãŒ0ã§ã‚‚1ã§ã‚‚ãªã‘ã‚Œã°ä¾‹å¤– + +## ã‚°ãƒãƒ¼ãƒãƒ«é–¢æ•° + +* `void init(const CurveParam& cp, size_t hashSize = 1024, size_t tryNum = 2048)`(C++) +* `void init(curveType = she.BN254, hashSize = 1024, tryNum = 2048)`(JS) + * hashSizeã®å¤§ãã•ã®å¾©å·ç”¨ãƒ†ãƒ¼ãƒ–ルã¨tryNumã‚’å…ƒã«åˆæœŸåŒ–ã™ã‚‹ + * 復å·å¯èƒ½ãªå¹³æ–‡mã®ç¯„囲ã¯|m| <= hashSize * tryNum +* `she.loadTableForGTDLP(Uint8Array a)`(JS) + * 復å·ç”¨ãƒ†ãƒ¼ãƒ–ルをèªã¿è¾¼ã‚€ + * ç¾åœ¨ã¯`https://herumi.github.io/she-dlp-table/she-dlp-0-20-gt.bin`ã®ã¿ãŒã‚ã‚‹ +* `void useDecG1ViaGT(bool use)`(C++/JS) +* `void useDecG2ViaGT(bool use)`(C++/JS) + * CipherTextG1, CipherTextG2ã®å¾©å·ã‚’CipherTextGT経由ã§è¡Œã† + * 大ããªå€¤ã‚’復å·ã™ã‚‹ã¨ãã¯DLP用ã®å·¨å¤§ãªãƒ†ãƒ¼ãƒ–ルをãã‚Œãžã‚Œã«æŒã¤ã‚ˆã‚Šã‚‚GTã«é›†ç´„ã—ãŸæ–¹ãŒåŠ¹çŽ‡ãŒã‚ˆã„ + +# ライセンス + +ã“ã®ãƒ©ã‚¤ãƒ–ラリã¯[ä¿®æ£BSDライセンス](https://github.com/herumi/mcl/blob/master/COPYRIGHT)ã§æä¾›ã•ã‚Œã¾ã™ + +# 開発者 + +å…‰æˆæ»‹ç”Ÿ MITSUNARI Shigeo(herumi@nifty.com) diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/she-api.md b/vendor/github.com/dexon-foundation/mcl/misc/she/she-api.md new file mode 100644 index 000000000..af54311e9 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/she-api.md @@ -0,0 +1,322 @@ +# she ; Two-level homomorphic encryption library for browser/Node.js by WebAssembly + +# Abstruct +she is a somewhat(two-level) homomorphic encryption library, +which is based on pairings. +This library supports polynomially many homomorphic additions and +one multiplication over encrypted data. + +Especially, the inner products of two encrypted integer vectors such as Enc(x) = (Enc(x_i)), Enc(y) = (Enc(y_i)) +can be computed. + +Sum_i Enc(x_i) Enc(y_i) = Enc(Sum_i x_i y_i). + +# Features +* supports the latest pairing based algorithm + * [Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and A Fast Implementation in WebAssembly : ASIA CCS2018](http://asiaccs2018.org/?page_id=632) +* supports Windows(x64), Linux(x64, ARM64), OSX(x64) +* supports JavaScript(WebAssembly), Chrome, Firefox, Safari(contains Android, iPhone), Node.js + +# Classes + +## Main classes +* secret key class ; SecretKey +* public key class ; PublicKey +* ciphertext class ; CipherTextG1, CipherTextG2, CipherTextGT +* zero-knowledge proof class ; ZkpBin, ZkpEq, ZkpBinEq + +## Encryption and decryption +* create the corresponding public key from a secret key +* encrypt an integer(plaintext) with a public key +* decrypt a ciphertext with a secret key + +## Homomorphic operations +* homomorphic addtion/substraction over ciphertexts of the same ciphertext class +* homomprphic multiplication over ciphertext of CipherTextG1 and CipherTextG2 + * The class of the result is CipherTextGT. + +## Important notation of decryption +* This library requires to solve a small DLP to decrypt a ciphertext. +* The decryption timing is O(m/s), where s is the size of table to solve DLP, and m is the size fo a plaintext. +* call `setRangeForDLP(s)` to set the table size. + * The maximun `m/s` is set by `setTryNum(tryNum)`. + +## Zero-knowledge proof class +* A zero-knowledge proof is simultaneously created when encrypting a plaintext `m`. +* The restriction according to `m` can be verified with a created zero-knowledge proof and a public key. + +# Setup for JavaScript(JS) + +## for Node.js + +``` +>npm install she-wasm +>node +>const she = require('she-wasm') +``` + +## for a browser + +Copy `she.js`, `she\_c.js`, `she\_c.wasm` to your directory from [she-wasm](https://github.com/herumi/she-wasm/), +and read `she.js`. +``` +// HTML +<script src="she.js"></script> +``` + +## A sample for JS + +``` +// initialize a library +she.init().then(() => { + const sec = new she.SecretKey() + // initialize a secret key by CSPRNG(cryptographically secure pseudo random number generator) + sec.setByCSPRNG() + + // create a public key from a secret key + const pub = sec.getPublicKey() + + const m1 = 1 + const m2 = 2 + const m3 = 3 + const m4 = -1 + + // encrypt m1 and m2 as CipherTextG1 class + const c11 = pub.encG1(m1) + const c12 = pub.encG1(m2) + + // encrypt m3 and m4 as CipherTextG2 class + const c21 = pub.encG2(m3) + const c22 = pub.encG2(m4) + + // add c11 and c12, c21 and c22 respectively + const c1 = she.add(c11, c12) + const c2 = she.add(c21, c22) + + // get ct as a CipherTextGT class by multiplying c1 with c2 + const ct = she.mul(c1, c2) + + // decrypt ct + console.log(`(${m1} + ${m2}) * (${m3} + ${m4}) = ${sec.dec(ct)}`) +}) +``` + +# A sample for C++ +How to build the library, see [mcl](https://github.com/herumi/mcl/#installation-requirements). +``` +#include <mcl/she.hpp> +int main() + try +{ + using namespace mcl::she; + // initialize a library + init(); + + SecretKey sec; + + // initialize a secret key by CSPRNG + sec.setByCSPRNG(); + + // create a public key from a secret key + PublicKey pub; + sec.getPublicKey(pub); + + int m1 = 1; + int m2 = 2; + int m3 = 3; + int m4 = -1; + + // encrypt m1 and m2 as CipherTextG1 class + CipherTextG1 c11, c12; + pub.enc(c11, m1); + pub.enc(c12, m2); + + // encrypt m3 and m4 as CipherTextG2 class + CipherTextG2 c21, c22; + pub.enc(c21, m3); + pub.enc(c22, m4); + + // add c11 and c12, c21 and c22 respectively + CipherTextG1 c1; + CipherTextG2 c2; + CipherTextG1::add(c1, c11, c12); + CipherTextG2::add(c2, c21, c22); + + // get ct as a CipherTextGT class by multiplying c1 with c2 + CipherTextGT ct; + CipherTextGT::mul(ct, c1, c2); + + // decrypt ct + printf("(%d + %d) * (%d + %d) = %d\n", m1, m2, m3, m4, (int)sec.dec(ct)); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} + +``` +# Class method + +## Serialization(C++) + +* `setStr(const std::string& str, int ioMode = 0)` + * set a value by `str` according to `ioMode` + +* `getStr(std::string& str, int ioMode = 0) const` +* `std::string getStr(int ioMode = 0) const` + * get a string `str` according to `ioMode` +* `size_t serialize(void *buf, size_t maxBufSize) const` + * serialize a value to buf which has maxBufSize byte size + * return the byte size to be written in `buf` + * return zero if error +* `size_t deserialize(const void *buf, size_t bufSize)` + * deserialize a value from buf which has bufSize byte size + * return the byte size to be read from `buf` + * return zero if error + +## Serialization(JS) + +* `deserialize(s)` + * deserialize from `s` as Uint8Array type +* `serialize()` + * serialize a value and return Uint8Array value +* `deserializeHexStr(s)` + * deserialize as a hexadecimal string +* `serializeToHexStr()` + * serialize as a hexadecimal string + +## ioMode + +* 2 ; binary number +* 10 ; decimal number +* 16 ; hexadecimal number +* IoPrefix ; append a prefix 0b(resp. 2) or 0x(resp. 16) +* IoEcAffine ; affine coordinate (for only G1, G2) +* IoEcProj ; projective coordinate (for only G1, G2) +* IoSerialize ; same as serialize()/deserialize() + +## Notation +* the namespace of C++ is `mcl::she` +* CT means one of CipherTextG1, CipherTextG2, CipherTextGT +* The range of plaintext is rectricted as a 32-bit integer for JS + +## SecretKey class + +* `void setByCSPRNG()`(C++) +* `void setByCSPRNG()`(JS) + * set a secret key by CSPRNG(cryptographically secure pseudo random number generator) + +* `int64_t dec(const CT& c) const`(C++) +* `int dec(CT c)`(JS) + * decrypt `c` +* `int64_t decViaGT(const CipherTextG1& c) const`(C++) +* `int64_t decViaGT(const CipherTextG2& c) const`(C++) +* `int decViaGT(CT c)`(JS) + * decrypt `c` through CipherTextGT +* `bool isZero(const CT& c) const`(C++) +* `bool isZero(CT c)`(JS) + * return true if decryption of `c` is zero + * it is faster than the timing of comparision with zero after decrypting `c` + +## PublicKey, PrecomputedPublicKey class +`PrecomputedPublicKey` is a faster version of `PublicKey` + +* `void PrecomputedPublicKey::init(const PublicKey& pub)`(C++) +* `void PrecomputedPublicKey::init(pub)`(JS) + * initialize `PrecomputedPublicKey` by a public key `pub` + +* `PrecomputedPublicKey::destroy()`(JS) + * It is necessary to call this method if this instance becomes unnecessary + * otherwise a memory leak will be caused + +PK means PublicKey or PrecomputedPublicKey + +* `void PK::enc(CT& c, int64_t m) const`(C++) +* `CipherTextG1 PK::encG1(m)`(JS) +* `CipherTextG2 PK::encG2(m)`(JS) +* `CipherTextGT PK::encGT(m)`(JS) + * encrypt `m` and set `c`(or return the value) + +* `void PK::reRand(CT& c) const`(C++) +* `CT PK::reRand(CT c)`(JS) + * rerandomize `c` + * For `c = Enc(m)`, the rerandomized ciphertext is hard to detect if it is generated by the rerandomization + or an encrypted `m` freshly again. + +* `void convert(CipherTextGT& cm, const CT& ca) const` +* `CipherTextGT convert(CT ca)` + * convert `ca`(CipherTextG1 or CipherTextG2) to `CipherTextGT` class + +## CipherText class + +* `void CT::add(CT& z, const CT& x const CT& y)`(C++) +* `CT she.add(CT x, CT y)`(JS) + * add `x` and `y` and set the value to `z`(or return the value) +* `void CT::sub(CT& z, const CT& x const CT& y)`(C++) +* `CT she.sub(CT x, CT y)`(JS) + * subtract `x` and `y` and set the value to `z`(or return the value) +* `void CT::neg(CT& y, const CT& x)`(C++) +* `void she.neg(CT x)`(JS) + * negate `x` and set the value to `y`(or return the value) +* `void CT::mul(CT& z, const CT& x, int y)`(C++) +* `CT she.mulInt(CT x, int y)`(JS) + * multiple `x` and `y` and set the value `y`(or return the value) + +* `void CipherTextGT::mul(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++) +* `CipherTextGT she.mul(CipherTextG1 x, CipherTextG2 y)`(JS) + * multiple `x` and `y` and set the value `y`(or return the value) + +* `void CipherTextGT::mulML(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++) + * multiple(only Miller Loop) `x` and `y` and set the value `y`(or return the value) + +* `CipherTextGT::finalExp(CipherText& , const CipherTextG1& x, const CipherTextG2& y)`(C++) + * mul(a, b) = finalExp(mulML(a, b)) + * add(mul(a, b), mul(c, d)) = finalExp(add(mulML(a, b), mulML(c, d))) + * i.e., innor product can be computed as once calling `finalExp` after computing `mulML` for each elements of two vectors and adding all + +## Zero knowledge proof class + +### Abstract +* ZkpBin ; verify whether `m = 0` or `1` for ciphertexts `encGi(m)(i = 1, 2, T)` +* ZkpEq ; verify whether `m1 = m2` for ciphertexts `encG1(m1)` and `encG2(m2)` +* ZkpBinEq ; verify whether `m1 = m2 = 0` or `1` for ciphertexts `encG1(m1)` and `encG2(m2)` + +### API +PK = PublicKey or PrecomputedPublicKey + +* `void PK::encWithZkpBin(CipherTextG1& c, Zkp& zkp, int m) const`(C++) +* `void PK::encWithZkpBin(CipherTextG2& c, Zkp& zkp, int m) const`(C++) +* `[CipherTextG1, ZkpBin] PK::encWithZkpBinG1(m)`(JS) +* `[CipherTextG2, ZkpBin] PK::encWithZkpBinG2(m)`(JS) + * encrypt `m`(=0 or 1) and set the ciphertext `c` and zero-knowledge proof `zkp`(or returns [c, zkp]) + * throw exception if m != 0 and m != 1 +* `void PK::encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const`(C++) +* `[CipherTextG1, CipherTextG2, ZkpEq] PK::encWithZkpEq(m)`(JS) + * encrypt `m` and set the ciphertext `c1`, `c2` and zero-knowledge proof `zk`(or returns [c1, c2, zkp]) +* `void PK::encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const`(C++) +* `[CipherTextG1, CipherTextG2, ZkpEqBin] PK::encWithZkpBinEq(m)`(JS) + * encrypt `m`(=0 or 1) and set ciphertexts `c1`, `c2` and zero-knowledge proof `zkp`(or returns [c1, c2, zkp]) + * throw exception if m != 0 and m != 1 + +## Global functions + +* `void init(const CurveParam& cp, size_t hashSize = 1024, size_t tryNum = 2048)`(C++) +* `void init(curveType = she.BN254, hashSize = 1024, tryNum = 2048)`(JS) + * initialize a table to solve a DLP with `hashSize` size and set maximum trying count `tryNum`. + * the range `m` to be solvable is |m| <= hashSize * tryNum +* `getHashTableGT().load(InputStream& is)`(C++) +* `she.loadTableForGTDLP(Uint8Array a)`(JS) + * load a DLP table for CipherTextGT + * reset the value of `hashSize` used in `init()` + * `https://herumi.github.io/she-dlp-table/she-dlp-0-20-gt.bin` is a precomputed table +* `void useDecG1ViaGT(bool use)`(C++/JS) +* `void useDecG2ViaGT(bool use)`(C++/JS) + * decrypt a ciphertext of CipherTextG1 and CipherTextG2 through CipherTextGT + * it is better when decrypt a big value + +# License + +[modified new BSD License](https://github.com/herumi/mcl/blob/master/COPYRIGHT) + +# Author + +å…‰æˆæ»‹ç”Ÿ MITSUNARI Shigeo(herumi@nifty.com) diff --git a/vendor/github.com/dexon-foundation/mcl/misc/she/she.pdf b/vendor/github.com/dexon-foundation/mcl/misc/she/she.pdf Binary files differnew file mode 100644 index 000000000..355a308b3 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/misc/she/she.pdf diff --git a/vendor/github.com/dexon-foundation/mcl/mklib.bat b/vendor/github.com/dexon-foundation/mcl/mklib.bat index b601f15d2..389b69009 100644 --- a/vendor/github.com/dexon-foundation/mcl/mklib.bat +++ b/vendor/github.com/dexon-foundation/mcl/mklib.bat @@ -23,6 +23,11 @@ if "%1"=="dll" ( cl /c %CFLAGS% src\bn_c384.cpp /Foobj\bn_c384.obj /DMCLBN_NO_AUTOLINK echo link /nologo /DLL /OUT:bin\mclbn384.dll obj\bn_c384.obj obj\fp.obj %LDFLAGS% /implib:lib\mclbn384.lib link /nologo /DLL /OUT:bin\mclbn384.dll obj\bn_c384.obj obj\fp.obj %LDFLAGS% /implib:lib\mclbn384.lib + + echo cl /c %CFLAGS% src\she_c256.cpp /Foobj\she_c256.obj /DMCLBN_NO_AUTOLINK + cl /c %CFLAGS% src\she_c256.cpp /Foobj\she_c256.obj /DMCLBN_NO_AUTOLINK + echo link /nologo /DLL /OUT:bin\mclshe256.dll obj\she_c256.obj obj\fp.obj %LDFLAGS% /implib:lib\mclshe_c256.lib + link /nologo /DLL /OUT:bin\mclshe256.dll obj\she_c256.obj obj\fp.obj %LDFLAGS% /implib:lib\mclshe_c256.lib ) else ( echo cl /c %CFLAGS% src\bn_c256.cpp /Foobj\bn_c256.obj cl /c %CFLAGS% src\bn_c256.cpp /Foobj\bn_c256.obj diff --git a/vendor/github.com/dexon-foundation/mcl/readme.md b/vendor/github.com/dexon-foundation/mcl/readme.md index 1a9f3acc0..39b3d4d42 100644 --- a/vendor/github.com/dexon-foundation/mcl/readme.md +++ b/vendor/github.com/dexon-foundation/mcl/readme.md @@ -10,6 +10,8 @@ mcl is a library for pairing-based cryptography. The current version supports the optimal Ate pairing over BN curves and BLS12-381 curves. # News +* (Break backward compatibility) libmcl_dy.a is renamed to libmcl.a + * The option SHARE_BASENAME_SUF is removed * 2nd argument of `mclBn_init` is changed from `maxUnitSize` to `compiledTimeVar`, which must be `MCLBN_COMPILED_TIME_VAR`. * break backward compatibility of mapToGi for BLS12. A map-to-function for BN is used. If `MCL_USE_OLD_MAPTO_FOR_BLS12` is defined, then the old function is used, but this will be removed in the future. @@ -35,33 +37,31 @@ p(z) = 36z^4 + 36z^3 + 24z^2 + 6z + 1. # Benchmark -A benchmark of a BN curve BN254(2016/12/25). +## The latest benchmark(2018/11/7) -* x64, x86 ; Inte Core i7-6700 3.4GHz(Skylake) upto 4GHz on Ubuntu 16.04. - * `sudo cpufreq-set -g performance` -* arm ; 900MHz quad-core ARM Cortex-A7 on Raspberry Pi2, Linux 4.4.11-v7+ -* arm64 ; 1.2GHz ARM Cortex-A53 [HiKey](http://www.96boards.org/product/hikey/) +### Intel Core i7-6700 3.4GHz(Skylake), Ubuntu 18.04.1 LTS -software | x64| x86| arm|arm64(msec) ----------------------------------------------------------|------|-----|----|----- -[ate-pairing](https://github.com/herumi/ate-pairing) | 0.21 | - | - | - -mcl | 0.31 | 1.6 |22.6| 3.9 -[TEPLA](http://www.cipher.risk.tsukuba.ac.jp/tepla/) | 1.76 | 3.7 | 37 | 17.9 -[RELIC](https://github.com/relic-toolkit/relic) PRIME=254| 0.30 | 3.5 | 36 | - -[MIRACL](https://github.com/miracl/MIRACL) ake12bnx | 4.2 | - | 78 | - -[NEONabe](http://sandia.cs.cinvestav.mx/Site/NEONabe) | - | - | 16 | - +curveType | binary|clang-6.0.0|gcc-7.3.0| +----------|--------------------|-----------|---------| +BN254 | bin/bn\_test.exe| 882Kclk| 933Kclk| +BLS12-381 | bin/bls12\_test.exe| 2290Kclk| 2630Kclk| -* compile option for RELIC -``` -cmake -DARITH=x64-asm-254 -DFP_PRIME=254 -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -``` -## Higher-bit BN curve benchmark by mcl +### Intel Core i7-7700 3.6GHz(Kaby Lake), Ubuntu 18.04.1 LTS on Windows 10 Vmware + +curveType | binary|clang-6.0.0|gcc-7.3.0| +----------|--------------------|-----------|---------| +BN254 | bin/bn\_test.exe| 900Kclk| 954Kclk| +BLS12-381 | bin/bls12\_test.exe| 2340Kclk| 2680Kclk| + +* now investigating the reason why gcc is slower than clang. + +## Higher-bit BN curve benchmark For JavaScript(WebAssembly), see [ID based encryption demo](https://herumi.github.io/mcl-wasm/ibe-demo.html). paramter | x64| Firefox on x64|Safari on iPhone7| -----------|-----|---------------|-----------------| -BN254 | 0.29| 2.48| 4.78| +BN254 | 0.25| 2.48| 4.78| BN381\_1 | 0.95| 7.91| 11.74| BN462 | 2.16| 14.73| 22.77| @@ -74,6 +74,27 @@ BN462 | 2.16| 14.73| 22.77| The other benchmark results are [bench.txt](bench.txt). +## An old benchmark of a BN curve BN254(2016/12/25). + +* x64, x86 ; Inte Core i7-6700 3.4GHz(Skylake) upto 4GHz on Ubuntu 16.04. + * `sudo cpufreq-set -g performance` +* arm ; 900MHz quad-core ARM Cortex-A7 on Raspberry Pi2, Linux 4.4.11-v7+ +* arm64 ; 1.2GHz ARM Cortex-A53 [HiKey](http://www.96boards.org/product/hikey/) + +software | x64| x86| arm|arm64(msec) +---------------------------------------------------------|------|-----|----|----- +[ate-pairing](https://github.com/herumi/ate-pairing) | 0.21 | - | - | - +mcl | 0.31 | 1.6 |22.6| 3.9 +[TEPLA](http://www.cipher.risk.tsukuba.ac.jp/tepla/) | 1.76 | 3.7 | 37 | 17.9 +[RELIC](https://github.com/relic-toolkit/relic) PRIME=254| 0.30 | 3.5 | 36 | - +[MIRACL](https://github.com/miracl/MIRACL) ake12bnx | 4.2 | - | 78 | - +[NEONabe](http://sandia.cs.cinvestav.mx/Site/NEONabe) | - | - | 16 | - + +* compile option for RELIC +``` +cmake -DARITH=x64-asm-254 -DFP_PRIME=254 -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" +``` + # Installation Requirements * [GMP](https://gmplib.org/) and OpenSSL @@ -90,6 +111,18 @@ git clone git://github.com/herumi/cybozulib_ext ; for only Windows ``` * Cybozulib\_ext is a prerequisite for running OpenSSL and GMP on VC (Visual C++). +# (Option) Without GMP +``` +make MCL_USE_GMP=0 +``` +Define `MCL_USE_VINT` before including `bn.hpp` + +# (Option) Without Openssl +``` +make MCL_USE_OPENSSL=0 +``` +Define `MCL_DONT_USE_OPENSSL` before including `bn.hpp` + # Build and test on x86-64 Linux, macOS, ARM and ARM64 Linux To make lib/libmcl.a and test it: ``` @@ -198,7 +231,7 @@ finalExp 546.259Kclk ## C++ library * libmcl.a ; static C++ library of mcl -* libmcl\_dy.so ; shared C++ library of mcl +* libmcl.so ; shared C++ library of mcl * the default parameter of curveType is BN254 header |support curveType |sizeof Fr|sizeof Fp| @@ -212,16 +245,22 @@ bn384.hpp |BN381_1, BLS12_381, BN254| 48 | 48 | * Define `MCLBN_FR_UNIT_SIZE` and `MCLBN_FP_UNIT_SIZE` and include bn.h * set `MCLBN_FR_UNIT_SIZE = MCLBN_FP_UNIT_SIZE` unless `MCLBN_FR_UNIT_SIZE` is defined + library |MCLBN_FR_UNIT_SIZE|MCLBN_FP_UNIT_SIZE| ------------------|------------------|------------------| +sizeof | Fr | Fp | libmclbn256.a | 4 | 4 | libmclbn384_256.a | 4 | 6 | libmclbn384.a | 6 | 6 | + * libmclbn*.a ; static C library -* libmclbn*\_dy.so ; shared C library +* libmclbn*.so ; shared C library -If you want to remove `_dy` of so files, then `makeSHARE_BASENAME\_SUF=`. +### 2nd argument of `mclBn_init` +Specify `MCLBN_COMPILED_TIME_VAR` to 2nd argument of `mclBn_init`, which +is defined as `MCLBN_FR_UNIT_SIZE * 10 + MCLBN_FP_UNIT_SIZE`. +This parameter is used to make sure that the values are the same when the library is built and used. # How to initialize pairing library Call `mcl::bn256::initPairing` before calling any operations. @@ -293,10 +332,14 @@ Use `Fp12::mulGeneric` for x in Fp12 - GT. ## Map To points -* mapToG1(G1& P, const Fp& x); +Use these functions to make a point of G1 and G2. + +* mapToG1(G1& P, const Fp& x); // assume x != 0 * mapToG2(G2& P, const Fp2& x); +* hashAndMapToG1(G1& P, const void *buf, size_t bufSize); // set P by the hash value of [buf, bufSize) +* hashAndMapToG2(G2& P, const void *buf, size_t bufSize); -These functions maps x into Gi according to [_Faster hashing to G2_]. +These functions maps x into Gi according to [\[_Faster hashing to G2_\]]. ## String format of G1 and G2 G1 and G2 have three elements of Fp (x, y, z) for Jacobi coordinate. @@ -309,6 +352,44 @@ getStr() method gets * `2 <x>` ; compressed format for even y * `3 <x>` ; compressed format for odd y +## Generator of G1 and G2 + +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, + +``` +// G1 P +P.setStr('1 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569') + +// G2 Q +Q.setStr('1 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582') +``` + +## Serialization format of G1 and G2 + +pseudo-code to serialize of p +``` +if bit-length(p) % 8 != 0: + size = Fp::getByteSize() + if p is zero: + return [0] * size + else: + s = x.serialize() + # x in Fp2 is odd <=> x.a is odd + if y is odd: + s[byte-length(s) - 1] |= 0x80 + return s +else: + size = Fp::getByteSize() + 1 + if p is zero: + return [0] * size + else: + s = x.serialize() + if y is odd: + return 2:s + else: + return 3:s +``` + ## Verify an element in G2 `G2::isValid()` checks that the element is in the curve of G2 and the order of it is r for subgroup attack. `G2::set()`, `G2::setStr` and `operator<<` also check the order. @@ -360,6 +441,17 @@ This library contains some part of the followings software licensed by BSD-3-Cla * [_Skew Frobenius Map and Efficient Scalar Multiplication for Pairing–Based Cryptography_](https://www.researchgate.net/publication/221282560_Skew_Frobenius_Map_and_Efficient_Scalar_Multiplication_for_Pairing-Based_Cryptography), Y. Sakemi, Y. Nogami, K. Okeya, Y. Morikawa, CANS 2008. +# History + +* 2019/Mar/22 v0.92 shortcut for Ec::mul(Px, P, x) if P = 0 +* 2019/Mar/21 python binding of she256 for Linux/Mac/Windows +* 2019/Mar/14 v0.91 modp supports mcl-wasm +* 2019/Mar/12 v0.90 fix Vint::setArray(x) for x == this +* 2019/Mar/07 add mclBnFr_setLittleEndianMod, mclBnFp_setLittleEndianMod +* 2019/Feb/20 LagrangeInterpolation sets out = yVec[0] if k = 1 +* 2019/Jan/31 add mclBnFp_mapToG1, mclBnFp2_mapToG2 +* 2019/Jan/31 fix crash on x64-CPU without AVX (thanks to mortdeus) + # Author å…‰æˆæ»‹ç”Ÿ MITSUNARI Shigeo(herumi@nifty.com) diff --git a/vendor/github.com/dexon-foundation/mcl/sample/bench.cpp b/vendor/github.com/dexon-foundation/mcl/sample/bench.cpp new file mode 100644 index 000000000..0f865b189 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/bench.cpp @@ -0,0 +1,233 @@ +#include <cybozu/benchmark.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> +#include <mcl/fp.hpp> +#include <mcl/conversion.hpp> +#include <mcl/ecparam.hpp> + +typedef mcl::FpT<> Fp; +typedef mcl::FpT<mcl::ZnTag> Zn; +typedef mcl::EcT<Fp> Ec; + +void benchFpSub(const char *pStr, const char *xStr, const char *yStr, mcl::fp::Mode mode) +{ + const char *s = mcl::fp::ModeToStr(mode); + Fp::init(pStr, mode); + Fp x(xStr); + Fp y(yStr); + + double addT, subT, mulT, sqrT, invT; + CYBOZU_BENCH_T(addT, Fp::add, x, x, x); + CYBOZU_BENCH_T(subT, Fp::sub, x, x, y); + CYBOZU_BENCH_T(mulT, Fp::mul, x, x, x); + CYBOZU_BENCH_T(sqrT, Fp::sqr, x, x); + CYBOZU_BENCH_T(invT, x += y;Fp::inv, x, x); // avoid same jmp + printf("%10s bit % 3d add %8.2f sub %8.2f mul %8.2f sqr %8.2f inv %8.2f\n", s, (int)Fp::getBitSize(), addT, subT, mulT, sqrT, invT); +} + +void benchFp(size_t bitSize, int mode) +{ + const struct { + size_t bitSize; + const char *p; + const char *x; + const char *y; + } tbl[] = { + { + 192, + "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", + "0x148094810948190412345678901234567900342423332197", + "0x7fffffffffffffffffffffe26f2fc170f69466a74defd8d", + }, + { + 256, + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", + "0x1480948109481904123456789234234242423424201234567900342423332197", + "0x151342342342341517fffffffffffffffffffffe26f2fc170f69466a74defd8d", + }, + { + 384, + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", + "0x19481084109481094820948209482094820984290482212345678901234567900342308472047204720422423332197", + "0x209348209481094820984209842094820948204204243123456789012345679003423084720472047204224233321972", + + }, + { + 521, + "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x2908209582095820941098410948109482094820984209840294829049240294242498540975555312345678901234567900342308472047204720422423332197", + "0x3948384209834029834092384204920349820948205872380573205782385729385729385723985837ffffffffffffffffffffffe26f2fc170f69466a74defd8d", + + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + if (bitSize != 0 && tbl[i].bitSize != bitSize) continue; + if (mode & 1) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP); + if (mode & 2) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP_MONT); +#ifdef MCL_USE_LLVM + if (mode & 4) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM); + if (mode & 8) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM_MONT); +#endif +#ifdef MCL_USE_XBYAK + if (mode & 16) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_XBYAK); +#endif + } +} + +void benchEcSub(const mcl::EcParam& para, mcl::fp::Mode mode, mcl::ec::Mode ecMode) +{ + Fp::init(para.p, mode); + Zn::init(para.n); + Ec::init(para.a, para.b, ecMode); + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y); + Ec P2; Ec::add(P2, P, P); + Ec Q = P + P + P; + double addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT; + CYBOZU_BENCH_T(addT, P = P2; Ec::add, Q, P, Q); + P.normalize(); + CYBOZU_BENCH_T(add2T, Ec::add, Q, P, Q); + CYBOZU_BENCH_T(subT, Ec::sub, Q, P, Q); + CYBOZU_BENCH_T(dblT, Ec::dbl, P, P); + Zn z("3"); + CYBOZU_BENCH_T(mulT, Ec::mul, Q, P, z); + CYBOZU_BENCH_T(mulCTT, Ec::mulCT, Q, P, z); + cybozu::XorShift rg; + z.setRand(rg); + CYBOZU_BENCH_T(mulRandT, Ec::mul, Q, P, z); + CYBOZU_BENCH_T(mulCTRandT, Ec::mulCT, Q, P, z); + CYBOZU_BENCH_T(normT, Q = P; Q.normalize); + printf("%10s %10s add %8.2f add2 %8.2f sub %8.2f dbl %8.2f mul(3) %8.2f mulCT(3) %8.2f mul(rand) %8.2f mulCT(rand) %8.2f norm %8.2f\n", para.name, mcl::fp::ModeToStr(mode), addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT); + +} +void benchEc(size_t bitSize, int mode, mcl::ec::Mode ecMode) +{ + const struct mcl::EcParam tbl[] = { + mcl::ecparam::p160_1, + mcl::ecparam::secp160k1, + mcl::ecparam::secp192k1, + mcl::ecparam::NIST_P192, + mcl::ecparam::secp224k1, + mcl::ecparam::secp256k1, + mcl::ecparam::NIST_P224, + mcl::ecparam::NIST_P256, +// mcl::ecparam::secp384r1, + mcl::ecparam::NIST_P384, +// mcl::ecparam::secp521r1, + mcl::ecparam::NIST_P521, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + if (bitSize != 0 && tbl[i].bitSize != bitSize) continue; + benchEcSub(tbl[i], mcl::fp::FP_AUTO, ecMode); + if (mode & 1) benchEcSub(tbl[i], mcl::fp::FP_GMP, ecMode); + if (mode & 2) benchEcSub(tbl[i], mcl::fp::FP_GMP_MONT, ecMode); +#ifdef MCL_USE_LLVM + if (mode & 4) benchEcSub(tbl[i], mcl::fp::FP_LLVM, ecMode); + if (mode & 8) benchEcSub(tbl[i], mcl::fp::FP_LLVM_MONT, ecMode); +#endif +#ifdef MCL_USE_XBYAK + if (mode & 16) benchEcSub(tbl[i], mcl::fp::FP_XBYAK, ecMode); +#endif + } +} + +void benchToStr16() +{ + puts("benchToStr16"); + const char *tbl[] = { + "0x0", + "0x5", + "0x123", + "0x123456789012345679adbc", + "0xffffffff26f2fc170f69466a74defd8d", + "0x100000000000000000000000000000033", + "0x11ee12312312940000000000000000000000000002342343" + }; + Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13"); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + char buf[128]; + std::string str; + Fp x(tbl[i]); + CYBOZU_BENCH("fp::arrayToHex", mcl::fp::arrayToHex, buf, sizeof(buf), x.getUnit(), x.getUnitSize(), true); + mpz_class y(tbl[i]); + CYBOZU_BENCH("gmp:getStr ", mcl::gmp::getStr, str, y, 16); + } +} + +void benchFromStr16() +{ + puts("benchFromStr16"); + const char *tbl[] = { + "0", + "5", + "123", + "123456789012345679adbc", + "ffffffff26f2fc170f69466a74defd8d", + "100000000000000000000000000000033", + "11ee12312312940000000000000000000000000002342343" + }; + Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13"); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + std::string str = tbl[i]; + Fp x; + const size_t N = 64; + mcl::fp::Unit buf[N]; + CYBOZU_BENCH("fp:hexToArray", mcl::fp::hexToArray, buf, N, str.c_str(), str.size()); + + mpz_class y; + CYBOZU_BENCH("gmp:setStr ", mcl::gmp::setStr, y, str, 16); + } +} + +int main(int argc, char *argv[]) + try +{ + size_t bitSize; + int mode; + bool ecOnly; + bool fpOnly; + bool misc; + mcl::ec::Mode ecMode; + std::string ecModeStr; + cybozu::Option opt; + opt.appendOpt(&bitSize, 0, "s", ": bitSize"); + opt.appendOpt(&mode, 0, "m", ": mode(0:all, sum of 1:gmp, 2:gmp+mont, 4:llvm, 8:llvm+mont, 16:xbyak"); + opt.appendBoolOpt(&ecOnly, "ec", ": ec only"); + opt.appendBoolOpt(&fpOnly, "fp", ": fp only"); + opt.appendBoolOpt(&misc, "misc", ": other benchmark"); + opt.appendOpt(&ecModeStr, "jacobi", "ecmode", ": jacobi or proj"); + opt.appendHelp("h", ": show this message"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + if (ecModeStr == "jacobi") { + ecMode = mcl::ec::Jacobi; + } else if (ecModeStr == "proj") { + ecMode = mcl::ec::Proj; + } else { + printf("bad ecstr %s\n", ecModeStr.c_str()); + opt.usage(); + return 1; + } + if (mode < 0 || mode > 31) { + printf("bad mode %d\n", mode); + opt.usage(); + return 1; + } + if (mode == 0) mode = 31; + if (misc) { + benchToStr16(); + benchFromStr16(); + } else { + if (!ecOnly) benchFp(bitSize, mode); + if (!fpOnly) { + printf("ecMode=%s\n", ecModeStr.c_str()); + benchEc(bitSize, mode, ecMode); + } + } +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); +} + diff --git a/vendor/github.com/dexon-foundation/mcl/sample/bls_sig.cpp b/vendor/github.com/dexon-foundation/mcl/sample/bls_sig.cpp new file mode 100644 index 000000000..d75f7d427 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/bls_sig.cpp @@ -0,0 +1,70 @@ +/** + @file + @brief a sample of BLS signature + see https://github.com/herumi/bls + @author MITSUNARI Shigeo(@herumi) + @license modified new BSD license + http://opensource.org/licenses/BSD-3-Clause + +*/ +#include <mcl/bn256.hpp> +#include <iostream> + +using namespace mcl::bn256; + +void Hash(G1& P, const std::string& m) +{ + Fp t; + t.setHashOf(m); + mapToG1(P, t); +} + +void KeyGen(Fr& s, G2& pub, const G2& Q) +{ + s.setRand(); + G2::mul(pub, Q, s); // pub = sQ +} + +void Sign(G1& sign, const Fr& s, const std::string& m) +{ + G1 Hm; + Hash(Hm, m); + G1::mul(sign, Hm, s); // sign = s H(m) +} + +bool Verify(const G1& sign, const G2& Q, const G2& pub, const std::string& m) +{ + Fp12 e1, e2; + G1 Hm; + Hash(Hm, m); + pairing(e1, sign, Q); // e1 = e(sign, Q) + pairing(e2, Hm, pub); // e2 = e(Hm, sQ) + return e1 == e2; +} + +int main(int argc, char *argv[]) +{ + std::string m = argc == 1 ? "hello mcl" : argv[1]; + + // setup parameter + initPairing(); + G2 Q; + mapToG2(Q, 1); + + // generate secret key and public key + Fr s; + G2 pub; + KeyGen(s, pub, Q); + std::cout << "secret key " << s << std::endl; + std::cout << "public key " << pub << std::endl; + + // sign + G1 sign; + Sign(sign, s, m); + std::cout << "msg " << m << std::endl; + std::cout << "sign " << sign << std::endl; + + // verify + bool ok = Verify(sign, Q, pub, m); + std::cout << "verify " << (ok ? "ok" : "ng") << std::endl; +} diff --git a/vendor/github.com/dexon-foundation/mcl/sample/ecdh.cpp b/vendor/github.com/dexon-foundation/mcl/sample/ecdh.cpp new file mode 100644 index 000000000..d5c4a31b2 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/ecdh.cpp @@ -0,0 +1,64 @@ +/* + sample of Elliptic Curve Diffie-Hellman key sharing +*/ +#include <iostream> +#include <fstream> +#include <cybozu/random_generator.hpp> +#include <mcl/fp.hpp> +#include <mcl/ecparam.hpp> + +typedef mcl::FpT<> Fp; +typedef mcl::FpT<mcl::ZnTag> Zn; +typedef mcl::EcT<Fp> Ec; + +int main() +{ + cybozu::RandomGenerator rg; + /* + system setup with a parameter secp192k1 recommended by SECG + Ec is an elliptic curve over Fp + the cyclic group of <P> is isomorphic to Zn + */ + const mcl::EcParam& para = mcl::ecparam::secp192k1; + Zn::init(para.n); + Fp::init(para.p); + Ec::init(para.a, para.b); + const Ec P(Fp(para.gx), Fp(para.gy)); + + /* + Alice setups a private key a and public key aP + */ + Zn a; + Ec aP; + + a.setRand(rg); + Ec::mul(aP, P, a); // aP = a * P; + + std::cout << "aP=" << aP << std::endl; + + /* + Bob setups a private key b and public key bP + */ + Zn b; + Ec bP; + + b.setRand(rg); + Ec::mul(bP, P, b); // bP = b * P; + + std::cout << "bP=" << bP << std::endl; + + Ec abP, baP; + + // Alice uses bP(B's public key) and a(A's priavte key) + Ec::mul(abP, bP, a); // abP = a * (bP) + + // Bob uses aP(A's public key) and b(B's private key) + Ec::mul(baP, aP, b); // baP = b * (aP) + + if (abP == baP) { + std::cout << "key sharing succeed:" << abP << std::endl; + } else { + std::cout << "ERR(not here)" << std::endl; + } +} + diff --git a/vendor/github.com/dexon-foundation/mcl/sample/large.cpp b/vendor/github.com/dexon-foundation/mcl/sample/large.cpp new file mode 100644 index 000000000..60b2ac900 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/large.cpp @@ -0,0 +1,125 @@ +/* + large prime sample for 64-bit arch + make MCL_USE_LLVM=1 MCL_MAX_BIT_SIZE=768 +*/ +#include <mcl/fp.hpp> +#include <cybozu/benchmark.hpp> +#include <iostream> +#include "../src/low_func.hpp" + +typedef mcl::FpT<> Fp; + +using namespace mcl::fp; +const size_t N = 12; + +void testMul() +{ + Unit ux[N], uy[N], a[N * 2], b[N * 2]; + for (size_t i = 0; i < N; i++) { + ux[i] = -i * i + 5; + uy[i] = -i * i + 9; + } + MulPreCore<N, Gtag>::f(a, ux, uy); + MulPreCore<N, Ltag>::f(b, ux, uy); + for (size_t i = 0; i < N * 2; i++) { + if (a[i] != b[i]) { + printf("ERR %016llx %016llx\n", (long long)a[i], (long long)b[i]); + } + } + puts("end testMul"); + CYBOZU_BENCH("gmp ", (MulPreCore<N, Gtag>::f), ux, ux, uy); + CYBOZU_BENCH("kara", (MulPre<N, Gtag>::karatsuba), ux, ux, uy); +} + +void mulGmp(mpz_class& z, const mpz_class& x, const mpz_class& y, const mpz_class& p) +{ + z = (x * y) % p; +} +void compareGmp(const std::string& pStr) +{ + Fp::init(pStr); + std::string xStr = "2104871209348712947120947102843728"; + std::string s1, s2; + { + Fp x(xStr); + CYBOZU_BENCH_C("mul by mcl", 1000, Fp::mul, x, x, x); + std::ostringstream os; + os << x; + s1 = os.str(); + } + { + const mpz_class p(pStr); + mpz_class x(xStr); + CYBOZU_BENCH_C("mul by GMP", 1000, mulGmp, x, x, x, p); + std::ostringstream os; + os << x; + s2 = os.str(); + } + if (s1 != s2) { + puts("ERR"); + } +} + +void test(const std::string& pStr, mcl::fp::Mode mode) +{ + printf("test %s\n", mcl::fp::ModeToStr(mode)); + Fp::init(pStr, mode); + const mcl::fp::Op& op = Fp::getOp(); + printf("bitSize=%d\n", (int)Fp::getBitSize()); + mpz_class p(pStr); + Fp x = 123456; + Fp y; + Fp::pow(y, x, p); + std::cout << y << std::endl; + if (x != y) { + std::cout << "err:pow:" << y << std::endl; + return; + } + const size_t N = 24; + mcl::fp::Unit ux[N], uy[N]; + for (size_t i = 0; i < N; i++) { + ux[i] = -i * i + 5; + uy[i] = -i * i + 9; + } + CYBOZU_BENCH("mulPre", op.fpDbl_mulPre, ux, ux, uy); + CYBOZU_BENCH("sqrPre", op.fpDbl_sqrPre, ux, ux); + CYBOZU_BENCH("add", op.fpDbl_add, ux, ux, ux, op.p); + CYBOZU_BENCH("sub", op.fpDbl_sub, ux, ux, ux, op.p); + if (op.fpDbl_addPre) { + CYBOZU_BENCH("addPre", op.fpDbl_addPre, ux, ux, ux); + CYBOZU_BENCH("subPre", op.fpDbl_subPre, ux, ux, ux); + } + CYBOZU_BENCH("mont", op.fpDbl_mod, ux, ux, op.p); + CYBOZU_BENCH("mul", Fp::mul, x, x, x); + compareGmp(pStr); +} + +void testAll(const std::string& pStr) +{ + test(pStr, mcl::fp::FP_GMP); + test(pStr, mcl::fp::FP_GMP_MONT); +#ifdef MCL_USE_LLVM + test(pStr, mcl::fp::FP_LLVM); + test(pStr, mcl::fp::FP_LLVM_MONT); +#endif + compareGmp(pStr); +} +int main() + try +{ + const char *pTbl[] = { + "40347654345107946713373737062547060536401653012956617387979052445947619094013143666088208645002153616185987062074179207", + "13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006083527", + "776259046150354467574489744231251277628443008558348305569526019013025476343188443165439204414323238975243865348565536603085790022057407195722143637520590569602227488010424952775132642815799222412631499596858234375446423426908029627", + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(pTbl); i++) { + testAll(pTbl[i]); + } + testMul(); +} catch (std::exception& e) { + printf("err %s\n", e.what()); + puts("make clean"); + puts("make -DMCL_MAX_BIT_SIZE=768"); + return 1; +} + diff --git a/vendor/github.com/dexon-foundation/mcl/sample/pairing.cpp b/vendor/github.com/dexon-foundation/mcl/sample/pairing.cpp new file mode 100644 index 000000000..230583b6e --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/pairing.cpp @@ -0,0 +1,56 @@ +#include <mcl/bn256.hpp> + +using namespace mcl::bn256; + +void minimum_sample(const G1& P, const G2& Q) +{ + const mpz_class a = 123; + const mpz_class b = 456; + Fp12 e1, e2; + pairing(e1, P, Q); + G2 aQ; + G1 bP; + G2::mul(aQ, Q, a); + G1::mul(bP, P, b); + pairing(e2, bP, aQ); + Fp12::pow(e1, e1, a * b); + printf("%s\n", e1 == e2 ? "ok" : "ng"); +} + +void miller_and_finel_exp(const G1& P, const G2& Q) +{ + Fp12 e1, e2; + pairing(e1, P, Q); + + millerLoop(e2, P, Q); + finalExp(e2, e2); + printf("%s\n", e1 == e2 ? "ok" : "ng"); +} + +void precomputed(const G1& P, const G2& Q) +{ + Fp12 e1, e2; + pairing(e1, P, Q); + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e2, P, Qcoeff); + finalExp(e2, e2); + printf("%s\n", e1 == e2 ? "ok" : "ng"); +} + +int main() +{ + const char *aa = "12723517038133731887338407189719511622662176727675373276651903807414909099441"; + const char *ab = "4168783608814932154536427934509895782246573715297911553964171371032945126671"; + const char *ba = "13891744915211034074451795021214165905772212241412891944830863846330766296736"; + const char *bb = "7937318970632701341203597196594272556916396164729705624521405069090520231616"; + + initPairing(); + G2 Q(Fp2(aa, ab), Fp2(ba, bb)); + G1 P(-1, 1); + + minimum_sample(P, Q); + miller_and_finel_exp(P, Q); + precomputed(P, Q); +} + diff --git a/vendor/github.com/dexon-foundation/mcl/sample/pairing_c.c b/vendor/github.com/dexon-foundation/mcl/sample/pairing_c.c new file mode 100644 index 000000000..5c2cd222a --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/pairing_c.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <string.h> +#define MCLBN_FP_UNIT_SIZE 4 +#include <mcl/bn.h> + +int g_err = 0; +#define ASSERT(x) { if (!(x)) { printf("err %s:%d\n", __FILE__, __LINE__); g_err++; } } + +int main() +{ + char buf[1024]; + const char *aStr = "123"; + const char *bStr = "456"; + mclBn_init(MCL_BN254, MCLBN_FP_UNIT_SIZE); + mclBnFr a, b, ab; + mclBnG1 P, aP; + mclBnG2 Q, bQ; + mclBnGT e, e1, e2; + mclBnFr_setStr(&a, aStr, strlen(aStr), 10); + mclBnFr_setStr(&b, bStr, strlen(bStr), 10); + mclBnFr_mul(&ab, &a, &b); + mclBnFr_getStr(buf, sizeof(buf), &ab, 10); + printf("%s x %s = %s\n", aStr, bStr, buf); + + ASSERT(!mclBnG1_hashAndMapTo(&P, "this", 4)); + ASSERT(!mclBnG2_hashAndMapTo(&Q, "that", 4)); + mclBnG1_getStr(buf, sizeof(buf), &P, 16); + printf("P = %s\n", buf); + mclBnG2_getStr(buf, sizeof(buf), &Q, 16); + printf("Q = %s\n", buf); + + mclBnG1_mul(&aP, &P, &a); + mclBnG2_mul(&bQ, &Q, &b); + + mclBn_pairing(&e, &P, &Q); + mclBnGT_getStr(buf, sizeof(buf), &e, 16); + printf("e = %s\n", buf); + mclBnGT_pow(&e1, &e, &a); + mclBn_pairing(&e2, &aP, &Q); + ASSERT(mclBnGT_isEqual(&e1, &e2)); + + mclBnGT_pow(&e1, &e, &b); + mclBn_pairing(&e2, &P, &bQ); + ASSERT(mclBnGT_isEqual(&e1, &e2)); + if (g_err) { + printf("err %d\n", g_err); + return 1; + } else { + printf("no err\n"); + return 0; + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/sample/random.cpp b/vendor/github.com/dexon-foundation/mcl/sample/random.cpp new file mode 100644 index 000000000..a2a3619ad --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/random.cpp @@ -0,0 +1,29 @@ +#include <mcl/fp.hpp> +#include <mcl/gmp_util.hpp> +#include <mcl/ecparam.hpp> +#include <cybozu/random_generator.hpp> +#include <map> +#include <mcl/fp.hpp> +typedef mcl::FpT<> Fp; + +typedef std::map<std::string, int> Map; + +int main(int argc, char *argv[]) +{ + cybozu::RandomGenerator rg; + const char *p = mcl::ecparam::secp192k1.p; + if (argc == 2) { + p = argv[1]; + } + Fp::init(p); + Fp x; + printf("p=%s\n", p); + Map m; + for (int i = 0; i < 10000; i++) { + x.setRand(rg); + m[x.getStr(16)]++; + } + for (Map::const_iterator i = m.begin(), ie = m.end(); i != ie; ++i) { + printf("%s %d\n", i->first.c_str(), i->second); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/sample/rawbench.cpp b/vendor/github.com/dexon-foundation/mcl/sample/rawbench.cpp new file mode 100644 index 000000000..4d7506ef5 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/rawbench.cpp @@ -0,0 +1,180 @@ +#define PUT(x) std::cout << #x "=" << (x) << std::endl +#include <cybozu/benchmark.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> +#include <mcl/fp.hpp> +#include <mcl/fp_tower.hpp> + +typedef mcl::FpT<mcl::FpTag> Fp; +typedef mcl::Fp2T<Fp> Fp2; +typedef mcl::FpDblT<Fp> FpDbl; +typedef mcl::Fp6T<Fp> Fp6; +typedef mcl::Fp12T<Fp> Fp12; + +typedef mcl::fp::Unit Unit; + +void mul9(const mcl::fp::Op& op, Unit *y, const Unit *x, const Unit *p) +{ + const size_t maxN = sizeof(Fp) / sizeof(Unit); + Unit tmp[maxN]; + op.fp_add(tmp, x, x, p); // 2x + op.fp_add(tmp, tmp, tmp, p); // 4x + op.fp_add(tmp, tmp, tmp, p); // 8x + op.fp_add(y, tmp, x, p); // 9x +} + +void benchRaw(const char *p, mcl::fp::Mode mode) +{ + Fp::init(1, p, mode); + Fp2::init(); + const size_t maxN = sizeof(Fp) / sizeof(Unit); + const mcl::fp::Op& op = Fp::getOp(); + cybozu::XorShift rg; + Fp fx, fy; + fx.setRand(rg); + fy.setRand(rg); + Unit ux[maxN * 2] = {}; + Unit uy[maxN * 2] = {}; + Unit uz[maxN * 2] = {}; + memcpy(ux, fx.getUnit(), sizeof(Unit) * op.N); + memcpy(ux + op.N, fx.getUnit(), sizeof(Unit) * op.N); + memcpy(uy, fy.getUnit(), sizeof(Unit) * op.N); + memcpy(ux + op.N, fx.getUnit(), sizeof(Unit) * op.N); + double fp_addT, fp_subT; + double fp_addPreT, fp_subPreT; + double fp_sqrT, fp_mulT; + double fp_mulUnitT; + double mul9T; + double fp_mulUnitPreT; + double fpN1_modT; + double fpDbl_addT, fpDbl_subT; + double fpDbl_sqrPreT, fpDbl_mulPreT, fpDbl_modT; + double fp2_sqrT, fp2_mulT; + CYBOZU_BENCH_T(fp_addT, op.fp_add, uz, ux, uy, op.p); + CYBOZU_BENCH_T(fp_subT, op.fp_sub, uz, uy, ux, op.p); + CYBOZU_BENCH_T(fp_addPreT, op.fp_addPre, uz, ux, uy); + CYBOZU_BENCH_T(fp_subPreT, op.fp_subPre, uz, uy, ux); + CYBOZU_BENCH_T(fp_sqrT, op.fp_sqr, uz, ux, op.p); + CYBOZU_BENCH_T(fp_mulT, op.fp_mul, uz, ux, uy, op.p); + CYBOZU_BENCH_T(fp_mulUnitT, op.fp_mulUnit, uz, ux, 9, op.p); + CYBOZU_BENCH_T(mul9T, mul9, op, uz, ux, op.p); + CYBOZU_BENCH_T(fp_mulUnitPreT, op.fp_mulUnitPre, ux, ux, 9); + CYBOZU_BENCH_T(fpN1_modT, op.fpN1_mod, ux, uy, op.p); + CYBOZU_BENCH_T(fpDbl_addT, op.fpDbl_add, uz, ux, uy, op.p); + CYBOZU_BENCH_T(fpDbl_subT, op.fpDbl_sub, uz, uy, ux, op.p); + CYBOZU_BENCH_T(fpDbl_sqrPreT, op.fpDbl_sqrPre, uz, ux); + CYBOZU_BENCH_T(fpDbl_mulPreT, op.fpDbl_mulPre, uz, ux, uy); + CYBOZU_BENCH_T(fpDbl_modT, op.fpDbl_mod, uz, ux, op.p); + Fp2 f2x, f2y; + f2x.a = fx; + f2x.b = fy; + f2y = f2x; + CYBOZU_BENCH_T(fp2_sqrT, Fp2::sqr, f2x, f2x); + CYBOZU_BENCH_T(fp2_mulT, Fp2::mul, f2x, f2x, f2y); + printf("%s\n", mcl::fp::ModeToStr(mode)); + const char *tStrTbl[] = { + "fp_add", "fp_sub", + "addPre", "subPre", + "fp_sqr", "fp_mul", + "mulUnit", + "mul9", + "mulUnitP", + "fpN1_mod", + "D_add", "D_sub", + "D_sqrPre", "D_mulPre", "D_mod", + "fp2_sqr", "fp2_mul", + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tStrTbl); i++) { + printf(" %8s", tStrTbl[i]); + } + printf("\n"); + const double tTbl[] = { + fp_addT, fp_subT, + fp_addPreT, fp_subPreT, + fp_sqrT, fp_mulT, + fp_mulUnitT, + mul9T, + fp_mulUnitPreT, + fpN1_modT, + fpDbl_addT, fpDbl_subT, + fpDbl_sqrPreT, fpDbl_mulPreT, fpDbl_modT, + fp2_sqrT, fp2_mulT, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tTbl); i++) { + printf(" %8.2f", tTbl[i]); + } + printf("\n"); +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + size_t bitSize; + opt.appendOpt(&bitSize, 0, "s", ": bitSize"); + opt.appendHelp("h", ": show this message"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + const char *tbl[] = { + // N = 2 + "0x0000000000000001000000000000000d", + "0x7fffffffffffffffffffffffffffffff", + "0x8000000000000000000000000000001d", + "0xffffffffffffffffffffffffffffff61", + + // N = 3 + "0x000000000000000100000000000000000000000000000033", // min prime + "0x70000000000000000000000000000000000000000000001f", + "0x800000000000000000000000000000000000000000000005", + "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", + "0xfffffffffffffffffffffffffffffffeffffffffffffffff", + "0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime + + // N = 4 + "0x0000000000000001000000000000000000000000000000000000000000000085", // min prime + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", // BN254 + "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47", // Snark + "0x7523648240000001ba344d80000000086121000000000013a700000000000017", + "0x800000000000000000000000000000000000000000000000000000000000005f", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime + // N = 5 + "0x80000000000000000000000000000000000000000000000000000000000000000000000000000009", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3b", + // N = 6 + "0x800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000171", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec3", + // N = 7 + "0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff35", + // N = 8 + "0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", +#if MCL_MAX_BIT_SIZE == 1024 + "0xc70b1ddda9b96e3965e5855942aa5852d8f8e052c760ac32cdfec16a2ed3d56981e1a475e20a70144ed2f5061ba64900f69451492803f815d446ee133d0668f7a7f3276d6301c95ce231f0e4b0d0f3882f10014fca04454cff55d2e2d4cfc1aad33b8d38397e2fc8b623177e63d0b783269c40a85b8f105654783b8ed2e737df", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff97", +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const char *p = tbl[i]; + if (bitSize > 0 && (strlen(p) - 2) * 4 != bitSize) { + continue; + } + printf("prime=%s\n", p); + benchRaw(tbl[i], mcl::fp::FP_GMP); + benchRaw(tbl[i], mcl::fp::FP_GMP_MONT); +#ifdef MCL_USE_LLVM + benchRaw(tbl[i], mcl::fp::FP_LLVM); + benchRaw(tbl[i], mcl::fp::FP_LLVM_MONT); +#endif +#ifdef MCL_USE_XBYAK + if (bitSize <= 384) { + benchRaw(tbl[i], mcl::fp::FP_XBYAK); + } +#endif + } +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/sample/she_make_dlp_table.cpp b/vendor/github.com/dexon-foundation/mcl/sample/she_make_dlp_table.cpp new file mode 100644 index 000000000..41f18e225 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/she_make_dlp_table.cpp @@ -0,0 +1,69 @@ +/* + make she DLP table +*/ +#include <mcl/she.hpp> +#include <cybozu/option.hpp> +#include <fstream> + +using namespace mcl::she; + +struct Param { + int curveType; + int hashBitSize; + int group; + std::string path; +}; + +template<class HashTable, class G> +void makeTable(const Param& param, const char *groupStr, HashTable& hashTbl, const G& P) +{ + char baseName[32]; + CYBOZU_SNPRINTF(baseName, sizeof(baseName), "she-dlp-%d-%d-%s.bin", param.curveType, param.hashBitSize, groupStr); + const std::string fileName = param.path + baseName; + printf("file=%s\n", fileName.c_str()); + std::ofstream ofs(fileName.c_str(), std::ios::binary); + + const size_t hashSize = 1u << param.hashBitSize; + hashTbl.init(P, hashSize); + hashTbl.save(ofs); +} + +void run(const Param& param) +{ + SHE::init(mcl::getCurveParam(param.curveType)); + + switch (param.group) { + case 1: + makeTable(param, "g1", getHashTableG1(), SHE::P_); + break; + case 2: + makeTable(param, "g2", getHashTableG2(), SHE::Q_); + break; + case 3: + makeTable(param, "gt", getHashTableGT(), SHE::ePQ_); + break; + default: + throw cybozu::Exception("bad group") << param.group; + } +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + Param param; + opt.appendOpt(¶m.curveType, 0, "ct", ": curveType(0:BN254, 1:BN381_1, 5:BLS12_381)"); + opt.appendOpt(¶m.hashBitSize, 20, "hb", ": hash bit size"); + opt.appendOpt(¶m.group, 3, "g", ": group(1:G1, 2:G2, 3:GT"); + opt.appendOpt(¶m.path, "./", "path", ": path to table"); + opt.appendHelp("h"); + if (opt.parse(argc, argv)) { + run(param); + } else { + opt.usage(); + return 1; + } +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/sample/she_smpl.cpp b/vendor/github.com/dexon-foundation/mcl/sample/she_smpl.cpp new file mode 100644 index 000000000..e01b9c130 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/she_smpl.cpp @@ -0,0 +1,125 @@ +/* + sample of somewhat homomorphic encryption(SHE) +*/ +#define PUT(x) std::cout << #x << "=" << (x) << std::endl; +#include <cybozu/benchmark.hpp> +#include <mcl/she.hpp> + +using namespace mcl::she; + +void miniSample() +{ + // init library + SHE::init(); + + SecretKey sec; + + // init secret key by random_device + sec.setByCSPRNG(); + + // set range to decode GT DLP + SHE::setRangeForDLP(1000); + + PublicKey pub; + // get public key + sec.getPublicKey(pub); + + const int N = 5; + int a[] = { 1, 5, -3, 4, 6 }; + int b[] = { 4, 2, 1, 9, -2 }; + // compute correct value + int sum = 0; + for (size_t i = 0; i < N; i++) { + sum += a[i] * b[i]; + } + + std::vector<CipherText> ca(N), cb(N); + + // encrypt each a[] and b[] + for (size_t i = 0; i < N; i++) { + pub.enc(ca[i], a[i]); + pub.enc(cb[i], b[i]); + } + CipherText c; + c.clearAsMultiplied(); // clear as multiplied before using c.add() + // inner product of encrypted vector + for (size_t i = 0; i < N; i++) { + CipherText t; + CipherText::mul(t, ca[i], cb[i]); // t = ca[i] * cb[i] + c.add(t); // c += t + } + // decode it + int m = (int)sec.dec(c); + // verify the value + if (m == sum) { + puts("ok"); + } else { + printf("err correct %d err %d\n", sum, m); + } +} + +void usePrimitiveCipherText() +{ + // init library + SHE::init(); + + SecretKey sec; + + // init secret key by random_device + sec.setByCSPRNG(); + + // set range to decode GT DLP + SHE::setRangeForGTDLP(100); + + PublicKey pub; + // get public key + sec.getPublicKey(pub); + + int a1 = 1, a2 = 2; + int b1 = 5, b2 = -4; + CipherTextG1 c1, c2; // size of CipherTextG1 = N * 2 ; N = 256-bit for CurveFp254BNb + CipherTextG2 d1, d2; // size of CipherTextG2 = N * 4 + pub.enc(c1, a1); + pub.enc(c2, a2); + pub.enc(d1, b1); + pub.enc(d2, b2); + c1.add(c2); // CipherTextG1 is additive HE + d1.add(d2); // CipherTextG2 is additive HE + CipherTextGT cm; // size of CipherTextGT = N * 12 * 4 + CipherTextGT::mul(cm, c1, d1); // cm = c1 * d1 + cm.add(cm); // 2cm + int m = (int)sec.dec(cm); + int ok = (a1 + a2) * (b1 + b2) * 2; + if (m == ok) { + puts("ok"); + } else { + printf("err m=%d ok=%d\n", m, ok); + } + std::string s; + s = c1.getStr(mcl::IoSerialize); // serialize + printf("c1 data size %d byte\n", (int)s.size()); + + c2.setStr(s, mcl::IoSerialize); + printf("deserialize %s\n", c1 == c2 ? "ok" : "ng"); + + s = d1.getStr(mcl::IoSerialize); // serialize + printf("d1 data size %d byte\n", (int)s.size()); + d2.setStr(s, mcl::IoSerialize); + printf("deserialize %s\n", d1 == d2 ? "ok" : "ng"); + + s = cm.getStr(mcl::IoSerialize); // serialize + printf("cm data size %d byte\n", (int)s.size()); + CipherTextGT cm2; + cm2.setStr(s, mcl::IoSerialize); + printf("deserialize %s\n", cm == cm2 ? "ok" : "ng"); +} + +int main() + try +{ + miniSample(); + usePrimitiveCipherText(); +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/sample/tri-dh.cpp b/vendor/github.com/dexon-foundation/mcl/sample/tri-dh.cpp new file mode 100644 index 000000000..8b720edbf --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/tri-dh.cpp @@ -0,0 +1,97 @@ +/* + tripartie Diffie-Hellman +*/ +#include <iostream> +#include <fstream> +#include <cybozu/random_generator.hpp> +#include <mcl/bn256.hpp> +#include <cybozu/option.hpp> + +static cybozu::RandomGenerator rg; + +const std::string skSuf = ".sk.txt"; +const std::string pkSuf = ".pk.txt"; + +using namespace mcl::bn256; + +void keygen(const std::string& user) +{ + if (user.empty()) { + throw cybozu::Exception("keygen:user is empty"); + } + const char *aa = "12723517038133731887338407189719511622662176727675373276651903807414909099441"; + const char *ab = "4168783608814932154536427934509895782246573715297911553964171371032945126671"; + const char *ba = "13891744915211034074451795021214165905772212241412891944830863846330766296736"; + const char *bb = "7937318970632701341203597196594272556916396164729705624521405069090520231616"; + + + initPairing(); + G2 Q(Fp2(aa, ab), Fp2(ba, bb)); + G1 P(-1, 1); + + Fr s; + s.setRand(rg); + G1::mul(P, P, s); + G2::mul(Q, Q, s); + { + std::string name = user + skSuf; + std::ofstream ofs(name.c_str(), std::ios::binary); + ofs << s << std::endl; + } + { + std::string name = user + pkSuf; + std::ofstream ofs(name.c_str(), std::ios::binary); + ofs << P << std::endl; + ofs << Q << std::endl; + } +} + +void load(G1& P, G2& Q, const std::string& fileName) +{ + std::ifstream ifs(fileName.c_str(), std::ios::binary); + ifs >> P >> Q; +} + +void share(const std::string& skFile, const std::string& pk1File, const std::string& pk2File) +{ + initPairing(); + Fr s; + G1 P1, P2; + G2 Q1, Q2; + { + std::ifstream ifs(skFile.c_str(), std::ios::binary); + ifs >> s; + } + load(P1, Q1, pk1File); + load(P2, Q2, pk2File); + Fp12 e; + pairing(e, P1, Q2); + { + // verify(not necessary) + Fp12 e2; + pairing(e2, P2, Q1); + if (e != e2) { + throw cybozu::Exception("share:bad public key file") << e << e2; + } + } + Fp12::pow(e, e, s); + std::cout << "share key:\n" << e << std::endl; +} + +int main(int argc, char *argv[]) + try +{ + if (argc == 3 && strcmp(argv[1], "keygen") == 0) { + keygen(argv[2]); + } else if (argc == 5 && strcmp(argv[1], "share") == 0) { + share(argv[2], argv[3], argv[4]); + } else { + fprintf(stderr, "tri-dh.exe keygen <user name>\n"); + fprintf(stderr, "tri-dh.exe share <secret key file> <public key1 file> <public key2 file>\n"); + return 1; + } +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} + diff --git a/vendor/github.com/dexon-foundation/mcl/sample/vote.cpp b/vendor/github.com/dexon-foundation/mcl/sample/vote.cpp new file mode 100644 index 000000000..88137187c --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/sample/vote.cpp @@ -0,0 +1,206 @@ +/* + vote sample tool + Copyright (c) 2014, National Institute of Advanced Industrial + Science and Technology All rights reserved. + This source file is subject to BSD 3-Clause license. + + modifyed for mcl by herumi +*/ +#include <iostream> +#include <fstream> +#include <cybozu/random_generator.hpp> +#include <cybozu/option.hpp> +#include <cybozu/itoa.hpp> +#include <mcl/fp.hpp> +#include <mcl/ec.hpp> +#include <mcl/elgamal.hpp> +#include <mcl/ecparam.hpp> + +typedef mcl::FpT<> Fp; +typedef mcl::FpT<mcl::ZnTag> Zn; // use ZnTag because Zn is different class with Fp +typedef mcl::EcT<Fp> Ec; +typedef mcl::ElgamalT<Ec, Zn> Elgamal; + +cybozu::RandomGenerator rg; + +const std::string pubFile = "vote_pub.txt"; +const std::string prvFile = "vote_prv.txt"; +const std::string resultFile = "vote_ret.txt"; + +std::string GetSheetName(size_t n) +{ + return std::string("vote_") + cybozu::itoa(n) + ".txt"; +} + +struct Param { + std::string mode; + std::string voteList; + Param(int argc, const char *const argv[]) + { + cybozu::Option opt; + opt.appendOpt(&voteList, "11001100", "l", ": list of voters for vote mode(eg. 11001100)"); + opt.appendHelp("h", ": put this message"); + opt.appendParam(&mode, "mode", ": init/vote/count/open"); + if (!opt.parse(argc, argv)) { + opt.usage(); + exit(1); + } + printf("mode=%s\n", mode.c_str()); + if (mode == "vote") { + printf("voters=%s\n", voteList.c_str()); + size_t pos = voteList.find_first_not_of("01"); + if (pos != std::string::npos) { + printf("bad char %c\n", voteList[pos]); + exit(1); + } + } + } +}; + +void SysInit() +{ + const mcl::EcParam& para = mcl::ecparam::secp192k1; + Zn::init(para.n); + Fp::init(para.p); + Ec::init(para.a, para.b); +} + +template<class T> +bool Load(T& t, const std::string& name, bool doThrow = true) +{ + std::ifstream ifs(name.c_str(), std::ios::binary); + if (!ifs) { + if (doThrow) throw cybozu::Exception("Load:can't read") << name; + return false; + } + if (ifs >> t) return true; + if (doThrow) throw cybozu::Exception("Load:bad data") << name; + return false; +} + +template<class T> +void Save(const std::string& name, const T& t) +{ + std::ofstream ofs(name.c_str(), std::ios::binary); + ofs << t; +} + +void Init() +{ + const mcl::EcParam& para = mcl::ecparam::secp192k1; + const Fp x0(para.gx); + const Fp y0(para.gy); + const Ec P(x0, y0); + const size_t bitSize = para.bitSize; + + Elgamal::PrivateKey prv; + prv.init(P, bitSize, rg); + const Elgamal::PublicKey& pub = prv.getPublicKey(); + printf("make privateKey=%s, publicKey=%s\n", prvFile.c_str(), pubFile.c_str()); + Save(prvFile, prv); + Save(pubFile, pub); +} + +struct CipherWithZkp { + Elgamal::CipherText c; + Elgamal::Zkp zkp; + bool verify(const Elgamal::PublicKey& pub) const + { + return pub.verify(c, zkp); + } +}; + +inline std::ostream& operator<<(std::ostream& os, const CipherWithZkp& self) +{ + return os << self.c << std::endl << self.zkp; +} +inline std::istream& operator>>(std::istream& is, CipherWithZkp& self) +{ + return is >> self.c >> self.zkp; +} + +void Vote(const std::string& voteList) +{ + Elgamal::PublicKey pub; + Load(pub, pubFile); + puts("shuffle"); + std::vector<size_t> idxTbl(voteList.size()); + for (size_t i = 0; i < idxTbl.size(); i++) { + idxTbl[i] = i; + } + cybozu::shuffle(idxTbl, rg); + puts("each voter votes"); + for (size_t i = 0; i < voteList.size(); i++) { + CipherWithZkp c; + pub.encWithZkp(c.c, c.zkp, voteList[i] - '0', rg); + const std::string sheetName = GetSheetName(idxTbl[i]); + printf("make %s\n", sheetName.c_str()); + Save(sheetName, c); + } +} + +void Count() +{ + Elgamal::PublicKey pub; + Load(pub, pubFile); + Elgamal::CipherText result; + puts("aggregate votes"); + for (size_t i = 0; ; i++) { + const std::string sheetName = GetSheetName(i); + CipherWithZkp c; + if (!Load(c, sheetName, false)) break; + if (!c.verify(pub)) throw cybozu::Exception("bad cipher text") << i; + printf("add %s\n", sheetName.c_str()); + result.add(c.c); + } + printf("create result file : %s\n", resultFile.c_str()); + Save(resultFile, result); +} + +void Open() +{ + Elgamal::PrivateKey prv; + Load(prv, prvFile); + Elgamal::CipherText c; + Load(c, resultFile); + Zn n; + prv.dec(n, c); + std::cout << "result of vote count " << n << std::endl; +#if 0 + puts("open real value"); + for (size_t i = 0; ; i++) { + Elgamal::CipherText c; + const std::string sheetName = GetSheetName(i); + if (!Load(c, sheetName, false)) break; + Zn n; + prv.dec(n, c); + std::cout << sheetName << " " << n << std::endl; + } +#endif +} + +int main(int argc, char *argv[]) + try +{ + const Param p(argc, argv); + SysInit(); + if (p.mode == "init") { + Init(); + } else + if (p.mode == "vote") { + Vote(p.voteList); + } else + if (p.mode == "count") { + Count(); + } else + if (p.mode == "open") { + Open(); + } else + { + printf("bad mode=%s\n", p.mode.c_str()); + return 1; + } +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); +} + diff --git a/vendor/github.com/dexon-foundation/mcl/src/bn_c256.cpp b/vendor/github.com/dexon-foundation/mcl/src/bn_c256.cpp index 5c3007410..2f975a287 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/bn_c256.cpp +++ b/vendor/github.com/dexon-foundation/mcl/src/bn_c256.cpp @@ -2,5 +2,5 @@ implementation of mclBn_* apis */ #define MCLBN_FP_UNIT_SIZE 4 -#include "bn_c_impl.hpp" +#include "mcl/impl/bn_c_impl.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/src/bn_c384.cpp b/vendor/github.com/dexon-foundation/mcl/src/bn_c384.cpp index 067e728f1..934a078ae 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/bn_c384.cpp +++ b/vendor/github.com/dexon-foundation/mcl/src/bn_c384.cpp @@ -3,5 +3,5 @@ */ #define MCLBN_FP_UNIT_SIZE 6 #define MCLBN_FR_UNIT_SIZE 6 -#include "bn_c_impl.hpp" +#include "mcl/impl/bn_c_impl.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/src/bn_c384_256.cpp b/vendor/github.com/dexon-foundation/mcl/src/bn_c384_256.cpp index 5630e831d..ecd968efd 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/bn_c384_256.cpp +++ b/vendor/github.com/dexon-foundation/mcl/src/bn_c384_256.cpp @@ -3,5 +3,5 @@ */ #define MCLBN_FP_UNIT_SIZE 6 #define MCLBN_FR_UNIT_SIZE 4 -#include "bn_c_impl.hpp" +#include "mcl/impl/bn_c_impl.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/src/bn_c512.cpp b/vendor/github.com/dexon-foundation/mcl/src/bn_c512.cpp index 90be2d9bc..7c1029522 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/bn_c512.cpp +++ b/vendor/github.com/dexon-foundation/mcl/src/bn_c512.cpp @@ -2,5 +2,5 @@ implementation of mclBn_* apis */ #define MCLBN_FP_UNIT_SIZE 8 -#include "bn_c_impl.hpp" +#include "mcl/impl/bn_c_impl.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/src/fp.cpp b/vendor/github.com/dexon-foundation/mcl/src/fp.cpp index bea1dff72..df72d6d07 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/fp.cpp +++ b/vendor/github.com/dexon-foundation/mcl/src/fp.cpp @@ -1,10 +1,6 @@ #include <mcl/op.hpp> #include <mcl/util.hpp> -#ifdef MCL_DONT_USE_OPENSSL #include <cybozu/sha2.hpp> -#else -#include <cybozu/crypto.hpp> -#endif #include <cybozu/endian.hpp> #include <mcl/conversion.hpp> #ifdef MCL_USE_XBYAK @@ -120,44 +116,16 @@ bool isEnableJIT() #endif } -void getRandVal(Unit *out, RandGen& rg, const Unit *in, size_t bitSize) -{ - if (rg.isZero()) rg = RandGen::get(); - const size_t n = (bitSize + UnitBitSize - 1) / UnitBitSize; - const size_t rem = bitSize & (UnitBitSize - 1); - assert(n > 0); - for (;;) { - rg.read(out, n * sizeof(Unit)); - if (rem > 0) out[n - 1] &= (Unit(1) << rem) - 1; - if (isLessArray(out, in, n)) return; - } -} - uint32_t sha256(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize) { - const uint32_t hashSize = 256 / 8; - if (maxOutSize < hashSize) return 0; -#ifdef MCL_DONT_USE_OPENSSL - cybozu::Sha256(msg, msgSize).get(out); -#else - cybozu::crypto::Hash::digest(out, cybozu::crypto::Hash::N_SHA256, msg, msgSize); -#endif - return hashSize; + return (uint32_t)cybozu::Sha256().digest(out, maxOutSize, msg, msgSize); } uint32_t sha512(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize) { - const uint32_t hashSize = 512 / 8; - if (maxOutSize < hashSize) return 0; -#ifdef MCL_DONT_USE_OPENSSL - cybozu::Sha512(msg, msgSize).get(out); -#else - cybozu::crypto::Hash::digest(out, cybozu::crypto::Hash::N_SHA512, msg, msgSize); -#endif - return hashSize; + return (uint32_t)cybozu::Sha512().digest(out, maxOutSize, msg, msgSize); } - #ifndef MCL_USE_VINT static inline void set_mpz_t(mpz_t& z, const Unit* p, int n) { @@ -350,9 +318,9 @@ static bool initForMont(Op& op, const Unit *p, Mode mode) if (mode != FP_XBYAK) return true; #ifdef MCL_USE_XBYAK if (op.fg == 0) op.fg = Op::createFpGenerator(); - op.fg->init(op); + bool useXbyak = op.fg->init(op); - if (op.isMont && N <= 4) { + if (useXbyak && op.isMont && N <= 4) { op.fp_invOp = &invOpForMontC; initInvTbl(op); } @@ -360,7 +328,7 @@ static bool initForMont(Op& op, const Unit *p, Mode mode) return true; } -bool Op::init(const mpz_class& _p, size_t maxBitSize, Mode mode, size_t mclMaxBitSize) +bool Op::init(const mpz_class& _p, size_t maxBitSize, int _xi_a, Mode mode, size_t mclMaxBitSize) { if (mclMaxBitSize != MCL_MAX_BIT_SIZE) return false; #ifdef MCL_USE_VINT @@ -382,6 +350,7 @@ bool Op::init(const mpz_class& _p, size_t maxBitSize, Mode mode, size_t mclMaxBi mp = _p; bitSize = gmp::getBitSize(mp); pmod4 = gmp::getUnit(mp, 0) % 4; + this->xi_a = _xi_a; /* priority : MCL_USE_XBYAK > MCL_USE_LLVM > none Xbyak > llvm_mont > llvm > gmp_mont > gmp @@ -497,18 +466,18 @@ bool Op::init(const mpz_class& _p, size_t maxBitSize, Mode mode, size_t mclMaxBi fpDbl_mod = &mcl::vint::mcl_fpDbl_mod_SECP256K1; } #endif - if (!fp::initForMont(*this, p, mode)) return false; - { - bool b; - sq.set(&b, mp); - if (!b) return false; - } if (N * UnitBitSize <= 256) { hash = sha256; } else { hash = sha512; } - return true; + { + bool b; + sq.set(&b, mp); + if (!b) return false; + } + modp.init(mp); + return fp::initForMont(*this, p, mode); } void copyUnitToByteAsLE(uint8_t *dst, const Unit *src, size_t byteSize) @@ -560,6 +529,27 @@ int detectIoMode(int ioMode, const std::ios_base& ios) bool copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, MaskMode maskMode) { const size_t fpByteSize = sizeof(Unit) * op.N; + if (maskMode == Mod) { + if (xByteSize > fpByteSize * 2) return false; + mpz_class mx; + bool b; + gmp::setArray(&b, mx, (const char*)x, xByteSize); + if (!b) return false; +#ifdef MCL_USE_VINT + op.modp.modp(mx, mx); +#else + mx %= op.mp; +#endif + const Unit *pmx = gmp::getUnit(mx); + size_t i = 0; + for (const size_t n = gmp::getUnitSize(mx); i < n; i++) { + y[i] = pmx[i]; + } + for (; i < op.N; i++) { + y[i] = 0; + } + return true; + } if (xByteSize > fpByteSize) { if (maskMode == NoMask) return false; xByteSize = fpByteSize; @@ -652,10 +642,5 @@ int64_t getInt64(bool *pb, fp::Block& b, const fp::Op& op) #pragma warning(pop) #endif -void Op::initFp2(int _xi_a) -{ - this->xi_a = _xi_a; -} - } } // mcl::fp diff --git a/vendor/github.com/dexon-foundation/mcl/src/fp_generator.hpp b/vendor/github.com/dexon-foundation/mcl/src/fp_generator.hpp index 581a0de87..b496bc4d4 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/fp_generator.hpp +++ b/vendor/github.com/dexon-foundation/mcl/src/fp_generator.hpp @@ -8,6 +8,7 @@ */ #if CYBOZU_HOST == CYBOZU_HOST_INTEL #define XBYAK_NO_OP_NAMES +#define XBYAK_DISABLE_AVX512 #include "xbyak/xbyak_util.h" #if MCL_SIZEOF_UNIT == 8 @@ -126,6 +127,71 @@ if (rm.isReg()) { \ namespace fp { +struct Profiler { + FILE *fp_; + const char *suf_; + const uint8_t *prev_; + Profiler() + : fp_(0) + , suf_(0) + , prev_(0) + { + } + void init(const char *suf, const uint8_t *prev) + { +#ifdef __linux__ + close(); + const char *s = getenv("MCL_PERF"); + if (s == 0 || strcmp(s, "1") != 0) return; + fprintf(stderr, "use perf suf=%s\n", suf); + suf_ = suf; + const int pid = getpid(); + char name[128]; + snprintf(name, sizeof(name), "/tmp/perf-%d.map", pid); + fp_ = fopen(name, "wb"); + if (fp_ == 0) throw cybozu::Exception("PerMap") << name; + prev_ = prev; +#else + (void)suf; + (void)prev; +#endif + } + ~Profiler() + { + close(); + } + void close() + { +#ifdef __linux__ + if (fp_ == 0) return; + fclose(fp_); + fp_ = 0; + prev_ = 0; +#endif + } + void set(const uint8_t *p, size_t n, const char *name) const + { +#ifdef __linux__ + if (fp_ == 0) return; + fprintf(fp_, "%llx %zx %s%s\n", (long long)p, n, name, suf_); +#else + (void)p; + (void)n; + (void)name; +#endif + } + void set(const char *name, const uint8_t *cur) + { +#ifdef __linux__ + set(prev_, cur - prev_, name); + prev_ = cur; +#else + (void)name; + (void)cur; +#endif + } +}; + struct FpGenerator : Xbyak::CodeGenerator { typedef Xbyak::RegExp RegExp; typedef Xbyak::Reg64 Reg64; @@ -192,28 +258,17 @@ struct FpGenerator : Xbyak::CodeGenerator { const Reg64& gt8; const Reg64& gt9; const mcl::fp::Op *op_; - Label *pL_; // valid only in init_inner + Label pL_; // pointer to p + // the following labels assume sf(this, 3, 10 | UseRDX) + Label mulPreL; + Label fpDbl_modL; + Label fp_mulL; const uint64_t *p_; uint64_t rp_; int pn_; int FpByte_; bool isFullBit_; - // add/sub without carry. return true if overflow - typedef bool (*bool3op)(uint64_t*, const uint64_t*, const uint64_t*); - - // add/sub with mod -// typedef void (*void3op)(uint64_t*, const uint64_t*, const uint64_t*); - - // mul without carry. return top of z - typedef uint64_t (*uint3opI)(uint64_t*, const uint64_t*, uint64_t); - - // neg - typedef void (*void2op)(uint64_t*, const uint64_t*); - - // preInv - typedef int (*int2op)(uint64_t*, const uint64_t*); - void4u mul_; -// uint3opI mulUnit_; + Profiler prof_; /* @param op [in] ; use op.p, op.N, op.isFullBit @@ -248,34 +303,25 @@ struct FpGenerator : Xbyak::CodeGenerator { , rp_(0) , pn_(0) , FpByte_(0) - , mul_(0) -// , mulUnit_(0) { useMulx_ = cpu_.has(Xbyak::util::Cpu::tBMI2); useAdx_ = cpu_.has(Xbyak::util::Cpu::tADX); } - void init(Op& op) + bool init(Op& op) { + if (!cpu_.has(Xbyak::util::Cpu::tAVX)) return false; reset(); // reset jit code for reuse setProtectModeRW(); // read/write memory init_inner(op); +// printf("code size=%d\n", (int)getSize()); setProtectModeRE(); // set read/exec memory + return true; } private: void init_inner(Op& op) { - // the following labels assume sf(this, 3, 10 | UseRDX) - Label mulPreL; - Label fpDbl_modL; - Label fp_mulL; - Label pL; // label to p_ op_ = &op; - pL_ = &pL; - /* - first 4096-byte is data area - remain is code area - */ - L(pL); + L(pL_); p_ = reinterpret_cast<const uint64_t*>(getCurr()); for (size_t i = 0; i < op.N; i++) { dq(op.p[i]); @@ -285,167 +331,101 @@ private: FpByte_ = int(op.maxN * sizeof(uint64_t)); isFullBit_ = op.isFullBit; // printf("p=%p, pn_=%d, isFullBit_=%d\n", p_, pn_, isFullBit_); - // code from here - setSize(4096); - assert((getCurr<size_t>() & 4095) == 0); - op.fp_addPre = getCurr<u3u>(); - gen_addSubPre(true, pn_); - align(16); - op.fp_subPre = getCurr<u3u>(); - gen_addSubPre(false, pn_); - align(16); - op.fp_sub = getCurr<void4u>(); - op.fp_subA_ = getCurr<void3u>(); - gen_fp_sub(); - align(16); - op.fp_add = getCurr<void4u>(); - op.fp_addA_ = getCurr<void3u>(); - gen_fp_add(); + static char suf[] = "_0"; + prof_.init(suf, getCurr()); + suf[1]++; - align(16); - op.fp_shr1 = getCurr<void2u>(); - gen_shr1(); + op.fp_addPre = gen_addSubPre(true, pn_); + prof_.set("Fp_addPre", getCurr()); - align(16); - op.fp_negA_ = getCurr<void2u>(); - gen_fp_neg(); + op.fp_subPre = gen_addSubPre(false, pn_); + prof_.set("Fp_subPre", getCurr()); - // setup fp_tower - op.fp2_mulNF = 0; - if (pn_ <= 4 || (pn_ == 6 && !isFullBit_)) { - align(16); - op.fpDbl_addA_ = getCurr<void3u>(); - gen_fpDbl_add(); - align(16); - op.fpDbl_subA_ = getCurr<void3u>(); - gen_fpDbl_sub(); - } - if (op.isFullBit) { - op.fpDbl_addPre = 0; - op.fpDbl_subPre = 0; - } else { - align(16); - op.fpDbl_addPreA_ = getCurr<void3u>(); - gen_addSubPre(true, pn_ * 2); - align(16); - op.fpDbl_subPreA_ = getCurr<void3u>(); - gen_addSubPre(false, pn_ * 2); - } - if ((useMulx_ && op.N == 2) || op.N == 3 || op.N == 4 || (useAdx_ && op.N == 6)) { - align(16); - op.fpDbl_mulPreA_ = getCurr<void3u>(); - if (op.N == 4) { - /* - fpDbl_mulPre is available as C function - this function calls mulPreL directly. - */ - StackFrame sf(this, 3, 10 | UseRDX, 0, false); - mulPre4(gp0, gp1, gp2, sf.t); - sf.close(); // make epilog - L(mulPreL); // called only from asm code - mulPre4(gp0, gp1, gp2, sf.t); - ret(); - } else if (op.N == 6 && useAdx_) { -#if 1 - StackFrame sf(this, 3, 7 | UseRDX, 0, false); - mulPre6(gp0, gp1, gp2, sf.t); - sf.close(); // make epilog - L(mulPreL); // called only from asm code - mulPre6(gp0, gp1, gp2, sf.t); - ret(); -#else - { - StackFrame sf(this, 3, 7 | UseRDX); - mulPre6(gp0, gp1, gp2, sf.t); - } - { - StackFrame sf(this, 3, 10 | UseRDX, 0, false); - L(mulPreL); // called only from asm code - mulPre6(gp0, gp1, gp2, sf.t); - ret(); - } -#endif - } else { - gen_fpDbl_mulPre(); - } - } - if (op.N == 2 || op.N == 3 || op.N == 4 || (op.N == 6 && !isFullBit_ && useAdx_)) { - align(16); - op.fpDbl_modA_ = getCurr<void2u>(); - if (op.N == 4) { - StackFrame sf(this, 3, 10 | UseRDX, 0, false); - call(fpDbl_modL); - sf.close(); - L(fpDbl_modL); - gen_fpDbl_mod4(gp0, gp1, sf.t, gp2); - ret(); - } else if (op.N == 6 && !isFullBit_ && useAdx_) { - StackFrame sf(this, 3, 10 | UseRDX, 0, false); - call(fpDbl_modL); - sf.close(); - L(fpDbl_modL); - Pack t = sf.t; - t.append(gp2); - gen_fpDbl_mod6(gp0, gp1, t); - ret(); - } else { - gen_fpDbl_mod(op); - } - } - if (op.N > 4) return; - if ((useMulx_ && op.N == 2) || op.N == 3 || op.N == 4) { - align(16); - op.fpDbl_sqrPreA_ = getCurr<void2u>(); - gen_fpDbl_sqrPre(op); + op.fp_addA_ = gen_fp_add(); + prof_.set("Fp_add", getCurr()); + + op.fp_subA_ = gen_fp_sub(); + prof_.set("Fp_sub", getCurr()); + + op.fp_shr1 = gen_shr1(); + prof_.set("Fp_shr1", getCurr()); + + op.fp_negA_ = gen_fp_neg(); + prof_.set("Fp_neg", getCurr()); + + op.fpDbl_addA_ = gen_fpDbl_add(); + prof_.set("FpDbl_add", getCurr()); + + op.fpDbl_subA_ = gen_fpDbl_sub(); + prof_.set("FpDbl_sub", getCurr()); + + op.fpDbl_addPre = gen_addSubPre(true, pn_ * 2); + prof_.set("FpDbl_addPre", getCurr()); + + op.fpDbl_subPre = gen_addSubPre(false, pn_ * 2); + prof_.set("FpDbl_subPre", getCurr()); + + op.fpDbl_mulPreA_ = gen_fpDbl_mulPre(); + prof_.set("FpDbl_mulPre", getCurr()); + + op.fpDbl_sqrPreA_ = gen_fpDbl_sqrPre(); + prof_.set("FpDbl_sqrPre", getCurr()); + + op.fpDbl_modA_ = gen_fpDbl_mod(op); + prof_.set("FpDbl_mod", getCurr()); + + op.fp_mulA_ = gen_mul(); + prof_.set("Fp_mul", getCurr()); + if (op.fp_mulA_) { + op.fp_mul = fp::func_ptr_cast<void4u>(op.fp_mulA_); // used in toMont/fromMont } - align(16); - op.fp_mul = getCurr<void4u>(); // used in toMont/fromMont - op.fp_mulA_ = getCurr<void3u>(); - gen_mul(fp_mulL); -// if (op.N > 4) return; - align(16); - op.fp_sqrA_ = getCurr<void2u>(); - gen_sqr(); + op.fp_sqrA_ = gen_sqr(); + prof_.set("Fp_sqr", getCurr()); + if (op.primeMode != PM_NIST_P192 && op.N <= 4) { // support general op.N but not fast for op.N > 4 align(16); op.fp_preInv = getCurr<int2u>(); gen_preInv(); + prof_.set("preInv", getCurr()); } - if (op.N == 4 && !isFullBit_) { - align(16); - op.fp2_addA_ = getCurr<void3u>(); - gen_fp2_add4(); - align(16); - op.fp2_subA_ = getCurr<void3u>(); - gen_fp2_sub4(); - align(16); - op.fp2_negA_ = getCurr<void2u>(); - gen_fp2_neg4(); - align(16); - op.fp2Dbl_mulPreA_ = getCurr<void3u>(); - gen_fp2Dbl_mulPre(mulPreL); - align(16); - op.fp2Dbl_sqrPreA_ = getCurr<void2u>(); - gen_fp2Dbl_sqrPre(mulPreL); - align(16); - op.fp2_mulA_ = getCurr<void3u>(); - gen_fp2_mul4(fpDbl_modL); - align(16); - op.fp2_sqrA_ = getCurr<void2u>(); - gen_fp2_sqr4(fp_mulL); - align(16); - op.fp2_mul_xiA_ = getCurr<void2u>(); - gen_fp2_mul_xi4(); - } + if (op.xi_a == 0) return; // Fp2 is not used + op.fp2_addA_ = gen_fp2_add(); + prof_.set("Fp2_add", getCurr()); + + op.fp2_subA_ = gen_fp2_sub(); + prof_.set("Fp2_sub", getCurr()); + + op.fp2_negA_ = gen_fp2_neg(); + prof_.set("Fp2_neg", getCurr()); + + op.fp2_mulNF = 0; + op.fp2Dbl_mulPreA_ = gen_fp2Dbl_mulPre(); + prof_.set("Fp2Dbl_mulPre", getCurr()); + + op.fp2Dbl_sqrPreA_ = gen_fp2Dbl_sqrPre(); + prof_.set("Fp2Dbl_sqrPre", getCurr()); + + op.fp2_mulA_ = gen_fp2_mul(); + prof_.set("Fp2_mul", getCurr()); + + op.fp2_sqrA_ = gen_fp2_sqr(); + prof_.set("Fp2_sqr", getCurr()); + + op.fp2_mul_xiA_ = gen_fp2_mul_xi(); + prof_.set("Fp2_mul_xi", getCurr()); } - void gen_addSubPre(bool isAdd, int n) + u3u gen_addSubPre(bool isAdd, int n) { +// if (isFullBit_) return 0; + align(16); + u3u func = getCurr<u3u>(); StackFrame sf(this, 3); if (isAdd) { gen_raw_add(sf.p[0], sf.p[1], sf.p[2], rax, n); } else { gen_raw_sub(sf.p[0], sf.p[1], sf.p[2], rax, n); } + return func; } /* pz[] = px[] + py[] @@ -498,7 +478,7 @@ private: } jmp(exit); L(nonZero); - mov(rax, (size_t)p_); + mov(rax, pL_); for (size_t i = 0; i < t.size(); i++) { mov(rdx, ptr [rax + i * 8]); if (i == 0) { @@ -626,7 +606,7 @@ private: mov(*fullReg, 0); adc(*fullReg, 0); } - mov(rax, (size_t)p_); + mov(rax, pL_); sub_rm(p1, rax); if (fullReg) { sbb(*fullReg, 0); @@ -646,7 +626,7 @@ private: const Pack& p1 = t.sub(pn_, pn_); load_rm(p0, px); sub_rm(p0, py, withCarry); - mov(rax, (size_t)p_); + mov(rax, pL_); load_rm(p1, rax); sbb(rax, rax); // rax = (x > y) ? 0 : -1 for (size_t i = 0; i < p1.size(); i++) { @@ -676,29 +656,29 @@ private: gen_raw_fp_sub(pz, px, py, sf.t, false); } /* - add(pz + offset, px + offset, py + offset); + add(pz, px, py); size of t1, t2 == 6 destroy t0, t1 */ - void gen_raw_fp_add6(const Reg64& pz, const Reg64& px, const Reg64& py, int offset, const Pack& t1, const Pack& t2, bool withCarry) + void gen_raw_fp_add6(const RegExp& pz, const RegExp& px, const RegExp& py, const Pack& t1, const Pack& t2, bool withCarry) { - load_rm(t1, px + offset); - add_rm(t1, py + offset, withCarry); + load_rm(t1, px); + add_rm(t1, py, withCarry); Label exit; if (isFullBit_) { jnc("@f"); - mov(t2[0], *pL_); // t2 is not used + mov(t2[0], pL_); // t2 is not used sub_rm(t1, t2[0]); jmp(exit); L("@@"); } mov_rr(t2, t1); - sub_rm(t2, rip + *pL_); + sub_rm(t2, rip + pL_); for (int i = 0; i < 6; i++) { cmovnc(t1[i], t2[i]); } L(exit); - store_mr(pz + offset, t1); + store_mr(pz, t1); } void gen_fp_add6() { @@ -713,17 +693,19 @@ private: Pack t2 = sf.t.sub(6); t2.append(rax); t2.append(px); // destory after used - gen_raw_fp_add6(pz, px, py, 0, t1, t2, false); + gen_raw_fp_add6(pz, px, py, t1, t2, false); } - void gen_fp_add() + void3u gen_fp_add() { + align(16); + void3u func = getCurr<void3u>(); if (pn_ <= 4) { gen_fp_add_le4(); - return; + return func; } if (pn_ == 6) { gen_fp_add6(); - return; + return func; } StackFrame sf(this, 3, 0, pn_ * 8); const Reg64& pz = sf.p[0]; @@ -733,7 +715,7 @@ private: inLocalLabel(); gen_raw_add(pz, px, py, rax, pn_); - mov(px, (size_t)p_); // destroy px + mov(px, pL_); // destroy px if (isFullBit_) { jc(".over", jmpMode); } @@ -759,9 +741,12 @@ private: L(".exit"); #endif outLocalLabel(); + return func; } - void gen_fpDbl_add() + void3u gen_fpDbl_add() { + align(16); + void3u func = getCurr<void3u>(); if (pn_ <= 4) { int tn = pn_ * 2 + (isFullBit_ ? 1 : 0); StackFrame sf(this, 3, tn); @@ -770,6 +755,7 @@ private: const Reg64& py = sf.p[2]; gen_raw_add(pz, px, py, rax, pn_); gen_raw_fp_add(pz + 8 * pn_, px + 8 * pn_, py + 8 * pn_, sf.t, true); + return func; } else if (pn_ == 6 && !isFullBit_) { StackFrame sf(this, 3, 10); const Reg64& pz = sf.p[0]; @@ -780,14 +766,15 @@ private: Pack t2 = sf.t.sub(6); t2.append(rax); t2.append(py); - gen_raw_fp_add6(pz, px, py, pn_ * 8, t1, t2, true); - } else { - assert(0); - exit(1); + gen_raw_fp_add6(pz + pn_ * 8, px + pn_ * 8, py + pn_ * 8, t1, t2, true); + return func; } + return 0; } - void gen_fpDbl_sub() + void3u gen_fpDbl_sub() { + align(16); + void3u func = getCurr<void3u>(); if (pn_ <= 4) { int tn = pn_ * 2; StackFrame sf(this, 3, tn); @@ -796,6 +783,7 @@ private: const Reg64& py = sf.p[2]; gen_raw_sub(pz, px, py, rax, pn_); gen_raw_fp_sub(pz + 8 * pn_, px + 8 * pn_, py + 8 * pn_, sf.t, true); + return func; } else if (pn_ == 6) { StackFrame sf(this, 3, 4); const Reg64& pz = sf.p[0]; @@ -806,12 +794,11 @@ private: t.append(rax); t.append(px); gen_raw_fp_sub6(pz, px, py, pn_ * 8, t, true); - } else { - assert(0); - exit(1); + return func; } + return 0; } - void gen_raw_fp_sub6(const Reg64& pz, const Reg64& px, const Reg64& py, int offset, const Pack& t, bool withCarry) + void gen_raw_fp_sub6(const RegExp& pz, const RegExp& px, const RegExp& py, int offset, const Pack& t, bool withCarry) { load_rm(t, px + offset); sub_rm(t, py + offset, withCarry); @@ -819,7 +806,7 @@ private: jmp is faster than and-mask without jmp */ jnc("@f"); - add_rm(t, rip + *pL_); + add_rm(t, rip + pL_); L("@@"); store_mr(pz + offset, t); } @@ -834,15 +821,17 @@ private: t.append(px); // |t| = 6 gen_raw_fp_sub6(pz, px, py, 0, t, false); } - void gen_fp_sub() + void3u gen_fp_sub() { + align(16); + void3u func = getCurr<void3u>(); if (pn_ <= 4) { gen_fp_sub_le4(); - return; + return func; } if (pn_ == 6) { gen_fp_sub6(); - return; + return func; } StackFrame sf(this, 3); const Reg64& pz = sf.p[0]; @@ -852,17 +841,23 @@ private: Label exit; gen_raw_sub(pz, px, py, rax, pn_); jnc(exit, jmpMode); - mov(px, (size_t)p_); + mov(px, pL_); gen_raw_add(pz, pz, px, rax, pn_); L(exit); + return func; } - void gen_fp_neg() + void2u gen_fp_neg() { + align(16); + void2u func = getCurr<void2u>(); StackFrame sf(this, 2, UseRDX | pn_); gen_raw_neg(sf.p[0], sf.p[1], sf.t); + return func; } - void gen_shr1() + void2u gen_shr1() { + align(16); + void2u func = getCurr<void2u>(); const int c = 1; StackFrame sf(this, 2, 1); const Reg64 *t0 = &rax; @@ -878,25 +873,54 @@ private: } shr(*t0, c); mov(ptr [pz + (pn_ - 1) * 8], *t0); + return func; } - void gen_mul(Label& fp_mulL) + void3u gen_mul() { + align(16); + void3u func = getCurr<void3u>(); if (op_->primeMode == PM_NIST_P192) { StackFrame sf(this, 3, 10 | UseRDX, 8 * 6); mulPre3(rsp, sf.p[1], sf.p[2], sf.t); fpDbl_mod_NIST_P192(sf.p[0], rsp, sf.t); + return func; } if (pn_ == 3) { - gen_montMul3(p_, rp_); - } else if (pn_ == 4) { - gen_montMul4(fp_mulL, p_, rp_); -// } else if (pn_ == 6 && useAdx_) { -// gen_montMul6(fp_mulL, p_, rp_); - } else if (pn_ <= 9) { + gen_montMul3(); + return func; + } + if (pn_ == 4) { + gen_montMul4(); + return func; + } + if (pn_ == 6 && !isFullBit_ && useMulx_ && useAdx_) { +#if 1 + // a little faster + gen_montMul6(); +#else + if (mulPreL.getAddress() == 0 || fpDbl_modL.getAddress() == 0) return 0; + StackFrame sf(this, 3, 10 | UseRDX, 12 * 8); + /* + use xm3 + rsp + [0, ..12 * 8) ; mul(x, y) + */ + vmovq(xm3, gp0); + mov(gp0, rsp); + call(mulPreL); // gp0, x, y + vmovq(gp0, xm3); + mov(gp1, rsp); + call(fpDbl_modL); +#endif + return func; + } +#if 0 + if (pn_ <= 9) { gen_montMulN(p_, rp_, pn_); - } else { - throw cybozu::Exception("mcl:FpGenerator:gen_mul:not implemented for") << pn_; + return func; } +#endif + return 0; } /* @input (z, xy) @@ -926,7 +950,7 @@ private: mov(a, rp_); mul(t6); - mov(t0, (uint64_t)p_); + mov(t0, pL_); mov(t7, a); // q // [d:t7:t1] = p * q @@ -995,7 +1019,7 @@ private: mov(a, rp_); mul(t10); - mov(t0, (uint64_t)p_); + mov(t0, pL_); mov(t7, a); // q // [d:t7:t2:t1] = p * q @@ -1070,12 +1094,12 @@ private: const Reg64& a = rax; const Reg64& d = rdx; - movq(xm0, z); + vmovq(xm0, z); mov(z, ptr [xy + 8 * 0]); mov(a, rp_); mul(z); - mov(t0, (uint64_t)p_); + mov(t0, pL_); mov(t7, a); // q // [d:t7:t3:t2:t1] = p * q @@ -1097,7 +1121,7 @@ private: if (isFullBit_) { mov(t5, 0); adc(t5, 0); - movq(xm2, t5); + vmovq(xm2, t5); } // free z, t0, t1, t5, t6, xy @@ -1106,18 +1130,18 @@ private: mul(t2); mov(z, a); // q - movq(xm1, t10); + vmovq(xm1, t10); // [d:z:t5:t6:xy] = p * q mul4x1(t0, z, t1, t5, t6, xy, t10); - movq(t10, xm1); + vmovq(t10, xm1); add_rr(Pack(t8, t4, t7, t3, t2), Pack(d, z, t5, t6, xy)); adc(t9, 0); adc(t10, 0); // [t10:t9:t8:t4:t7:t3] if (isFullBit_) { - movq(t5, xm2); + vmovq(t5, xm2); adc(t5, 0); - movq(xm2, t5); + vmovq(xm2, t5); } // free z, t0, t1, t2, t5, t6, xy @@ -1132,7 +1156,7 @@ private: add_rr(Pack(t9, t8, t4, t7, t3), Pack(d, z, t5, xy, t6)); adc(t10, 0); // c' = [t10:t9:t8:t4:t7] if (isFullBit_) { - movq(t3, xm2); + vmovq(t3, xm2); adc(t3, 0); } @@ -1161,60 +1185,112 @@ private: cmovc(t9, t2); cmovc(t10, t6); - movq(z, xm0); + vmovq(z, xm0); store_mr(z, Pack(t10, t9, t8, t4)); } - void gen_fpDbl_mod(const mcl::fp::Op& op) + void2u gen_fpDbl_mod(const fp::Op& op) { + align(16); + void2u func = getCurr<void2u>(); if (op.primeMode == PM_NIST_P192) { StackFrame sf(this, 2, 6 | UseRDX); fpDbl_mod_NIST_P192(sf.p[0], sf.p[1], sf.t); - return; + return func; } #if 0 if (op.primeMode == PM_NIST_P521) { StackFrame sf(this, 2, 8 | UseRDX); fpDbl_mod_NIST_P521(sf.p[0], sf.p[1], sf.t); - return; + return func; } #endif - switch (pn_) { - case 2: + if (pn_ == 2) { gen_fpDbl_mod2(); - break; - case 3: + return func; + } + if (pn_ == 3) { gen_fpDbl_mod3(); - break; -#if 0 - case 4: - { - StackFrame sf(this, 3, 10 | UseRDX); - gen_fpDbl_mod4(gp0, gp1, sf.t, gp2); - } - break; -#endif - default: - throw cybozu::Exception("gen_fpDbl_mod:not support") << pn_; + return func; + } + if (pn_ == 4) { + StackFrame sf(this, 3, 10 | UseRDX, 0, false); + call(fpDbl_modL); + sf.close(); + L(fpDbl_modL); + gen_fpDbl_mod4(gp0, gp1, sf.t, gp2); + ret(); + return func; + } + if (pn_ == 6 && !isFullBit_ && useMulx_ && useAdx_) { + StackFrame sf(this, 3, 10 | UseRDX, 0, false); + call(fpDbl_modL); + sf.close(); + L(fpDbl_modL); + Pack t = sf.t; + t.append(gp2); + gen_fpDbl_mod6(gp0, gp1, t); + ret(); + return func; } + return 0; } - void gen_sqr() + void2u gen_sqr() { + align(16); + void2u func = getCurr<void2u>(); if (op_->primeMode == PM_NIST_P192) { - StackFrame sf(this, 2, 10 | UseRDX | UseRCX, 8 * 6); - sqrPre3(rsp, sf.p[1], sf.t); + StackFrame sf(this, 3, 10 | UseRDX, 6 * 8); + Pack t = sf.t; + t.append(sf.p[2]); + sqrPre3(rsp, sf.p[1], t); fpDbl_mod_NIST_P192(sf.p[0], rsp, sf.t); + return func; } if (pn_ == 3) { - gen_montSqr3(p_, rp_); - return; + gen_montSqr3(); + return func; } - // sqr(y, x) = mul(y, x, x) + if (pn_ == 4 && useMulx_) { +#if 1 + // sqr(y, x) = mul(y, x, x) #ifdef XBYAK64_WIN - mov(r8, rdx); + mov(r8, rdx); #else - mov(rdx, rsi); + mov(rdx, rsi); +#endif + jmp((const void*)op_->fp_mulA_); +#else // (sqrPre + mod) is slower than mul + StackFrame sf(this, 3, 10 | UseRDX, 8 * 8); + Pack t = sf.t; + t.append(sf.p[2]); + sqrPre4(rsp, sf.p[1], t); + mov(gp0, sf.p[0]); + mov(gp1, rsp); + call(fpDbl_modL); #endif - jmp((const void*)op_->fp_mulA_); + return func; + } + if (pn_ == 6 && !isFullBit_ && useMulx_ && useAdx_) { + if (fpDbl_modL.getAddress() == 0) return 0; + StackFrame sf(this, 3, 10 | UseRDX, (12 + 6) * 8); + /* + use xm3 + rsp + [6 * 8, (12 + 6) * 8) ; sqrPre(x, x) + [0..6 * 8) ; stack for sqrPre6 + */ + vmovq(xm3, gp0); + Pack t = sf.t; + t.append(sf.p[2]); + // sqrPre6 uses 6 * 8 bytes stack + sqrPre6(rsp + 6 * 8, sf.p[1], t); + mov(gp0, ptr[rsp + (12 + 6) * 8]); + vmovq(gp0, xm3); + lea(gp1, ptr[rsp + 6 * 8]); + call(fpDbl_modL); + return func; + } + return 0; } /* input (pz[], px[], py[]) @@ -1259,7 +1335,7 @@ private: z[0..3] <- montgomery(x[0..3], y[0..3]) destroy gt0, ..., gt9, xm0, xm1, p2 */ - void gen_montMul4(Label& fp_mulL, const uint64_t *p, uint64_t pp) + void gen_montMul4() { StackFrame sf(this, 3, 10 | UseRDX, 0, false); call(fp_mulL); @@ -1280,23 +1356,23 @@ private: const Reg64& t9 = sf.t[9]; L(fp_mulL); - movq(xm0, p0); // save p0 - mov(p0, (uint64_t)p); - movq(xm1, p2); + vmovq(xm0, p0); // save p0 + mov(p0, pL_); + vmovq(xm1, p2); mov(p2, ptr [p2]); - montgomery4_1(pp, t0, t7, t3, t2, t1, p1, p2, p0, t4, t5, t6, t8, t9, true, xm2); + montgomery4_1(rp_, t0, t7, t3, t2, t1, p1, p2, p0, t4, t5, t6, t8, t9, true, xm2); - movq(p2, xm1); + vmovq(p2, xm1); mov(p2, ptr [p2 + 8]); - montgomery4_1(pp, t1, t0, t7, t3, t2, p1, p2, p0, t4, t5, t6, t8, t9, false, xm2); + montgomery4_1(rp_, t1, t0, t7, t3, t2, p1, p2, p0, t4, t5, t6, t8, t9, false, xm2); - movq(p2, xm1); + vmovq(p2, xm1); mov(p2, ptr [p2 + 16]); - montgomery4_1(pp, t2, t1, t0, t7, t3, p1, p2, p0, t4, t5, t6, t8, t9, false, xm2); + montgomery4_1(rp_, t2, t1, t0, t7, t3, p1, p2, p0, t4, t5, t6, t8, t9, false, xm2); - movq(p2, xm1); + vmovq(p2, xm1); mov(p2, ptr [p2 + 24]); - montgomery4_1(pp, t3, t2, t1, t0, t7, p1, p2, p0, t4, t5, t6, t8, t9, false, xm2); + montgomery4_1(rp_, t3, t2, t1, t0, t7, p1, p2, p0, t4, t5, t6, t8, t9, false, xm2); // [t7:t3:t2:t1:t0] mov(t4, t0); @@ -1310,16 +1386,131 @@ private: cmovc(t2, t6); cmovc(t3, rdx); - movq(p0, xm0); // load p0 + vmovq(p0, xm0); // load p0 store_mr(p0, Pack(t3, t2, t1, t0)); ret(); } /* + c[n+2] = c[n+1] + px[n] * rdx + use rax + */ + void mulAdd(const Pack& c, int n, const RegExp& px) + { + const Reg64& a = rax; + xor_(a, a); + for (int i = 0; i < n; i++) { + mulx(c[n + 1], a, ptr [px + i * 8]); + adox(c[i], a); + adcx(c[i + 1], c[n + 1]); + } + mov(a, 0); + mov(c[n + 1], a); + adox(c[n], a); + adcx(c[n + 1], a); + adox(c[n + 1], a); + } + /* + input + c[6..0] + rdx = yi + use rax, rdx + output + c[7..1] + + if first: + c = x[5..0] * rdx + else: + c += x[5..0] * rdx + q = uint64_t(c0 * rp) + c += p * q + c >>= 64 + */ + void montgomery6_1(const Pack& c, const RegExp& px, const Reg64& t0, const Reg64& t1, bool isFirst) + { + const int n = 6; + const Reg64& a = rax; + const Reg64& d = rdx; + if (isFirst) { + const Reg64 *pt0 = &a; + const Reg64 *pt1 = &t0; + // c[6..0] = px[5..0] * rdx + mulx(*pt0, c[0], ptr [px + 0 * 8]); + for (int i = 1; i < n; i++) { + mulx(*pt1, c[i], ptr[px + i * 8]); + if (i == 1) { + add(c[i], *pt0); + } else { + adc(c[i], *pt0); + } + std::swap(pt0, pt1); + } + mov(c[n], 0); + adc(c[n], *pt0); + } else { + // c[7..0] = c[6..0] + px[5..0] * rdx + mulAdd(c, 6, px); + } + mov(a, rp_); + mul(c[0]); // q = a + mov(d, a); + mov(t1, pL_); + // c += p * q + mulAdd(c, 6, t1); + } + /* + input (z, x, y) = (p0, p1, p2) + z[0..5] <- montgomery(x[0..5], y[0..5]) + destroy t0, ..., t9, rax, rdx + */ + void gen_montMul6() + { + assert(!isFullBit_ && useMulx_ && useAdx_); + StackFrame sf(this, 3, 10 | UseRDX, 0, false); + call(fp_mulL); + sf.close(); + const Reg64& pz = sf.p[0]; + const Reg64& px = sf.p[1]; + const Reg64& py = sf.p[2]; + + const Reg64& t0 = sf.t[0]; + const Reg64& t1 = sf.t[1]; + const Reg64& t2 = sf.t[2]; + const Reg64& t3 = sf.t[3]; + const Reg64& t4 = sf.t[4]; + const Reg64& t5 = sf.t[5]; + const Reg64& t6 = sf.t[6]; + const Reg64& t7 = sf.t[7]; + const Reg64& t8 = sf.t[8]; + const Reg64& t9 = sf.t[9]; + L(fp_mulL); + mov(rdx, ptr [py + 0 * 8]); + montgomery6_1(Pack(t7, t6, t5, t4, t3, t2, t1, t0), px, t8, t9, true); + mov(rdx, ptr [py + 1 * 8]); + montgomery6_1(Pack(t0, t7, t6, t5, t4, t3, t2, t1), px, t8, t9, false); + mov(rdx, ptr [py + 2 * 8]); + montgomery6_1(Pack(t1, t0, t7, t6, t5, t4, t3, t2), px, t8, t9, false); + mov(rdx, ptr [py + 3 * 8]); + montgomery6_1(Pack(t2, t1, t0, t7, t6, t5, t4, t3), px, t8, t9, false); + mov(rdx, ptr [py + 4 * 8]); + montgomery6_1(Pack(t3, t2, t1, t0, t7, t6, t5, t4), px, t8, t9, false); + mov(rdx, ptr [py + 5 * 8]); + montgomery6_1(Pack(t4, t3, t2, t1, t0, t7, t6, t5), px, t8, t9, false); + // [t4:t3:t2:t1:t0:t7:t6] + const Pack z = Pack(t3, t2, t1, t0, t7, t6); + const Pack keep = Pack(rdx, rax, px, py, t8, t9); + mov_rr(keep, z); + mov(t5, pL_); + sub_rm(z, t5); + cmovc_rr(z, keep); + store_mr(pz, z); + ret(); + } + /* input (z, x, y) = (p0, p1, p2) z[0..2] <- montgomery(x[0..2], y[0..2]) destroy gt0, ..., gt9, xm0, xm1, p2 */ - void gen_montMul3(const uint64_t *p, uint64_t pp) + void gen_montMul3() { StackFrame sf(this, 3, 10 | UseRDX); const Reg64& p0 = sf.p[0]; @@ -1337,16 +1528,16 @@ private: const Reg64& t8 = sf.t[8]; const Reg64& t9 = sf.t[9]; - movq(xm0, p0); // save p0 - mov(t7, (uint64_t)p); + vmovq(xm0, p0); // save p0 + mov(t7, pL_); mov(t9, ptr [p2]); // c3, c2, c1, c0, px, y, p, - montgomery3_1(pp, t0, t3, t2, t1, p1, t9, t7, t4, t5, t6, t8, p0, true); + montgomery3_1(rp_, t0, t3, t2, t1, p1, t9, t7, t4, t5, t6, t8, p0, true); mov(t9, ptr [p2 + 8]); - montgomery3_1(pp, t1, t0, t3, t2, p1, t9, t7, t4, t5, t6, t8, p0, false); + montgomery3_1(rp_, t1, t0, t3, t2, p1, t9, t7, t4, t5, t6, t8, p0, false); mov(t9, ptr [p2 + 16]); - montgomery3_1(pp, t2, t1, t0, t3, p1, t9, t7, t4, t5, t6, t8, p0, false); + montgomery3_1(rp_, t2, t1, t0, t3, p1, t9, t7, t4, t5, t6, t8, p0, false); // [(t3):t2:t1:t0] mov(t4, t0); @@ -1357,7 +1548,7 @@ private: cmovc(t0, t4); cmovc(t1, t5); cmovc(t2, t6); - movq(p0, xm0); + vmovq(p0, xm0); store_mr(p0, Pack(t2, t1, t0)); } /* @@ -1365,7 +1556,7 @@ private: z[0..2] <- montgomery(px[0..2], px[0..2]) destroy gt0, ..., gt9, xm0, xm1, p2 */ - void gen_montSqr3(const uint64_t *p, uint64_t pp) + void gen_montSqr3() { StackFrame sf(this, 3, 10 | UseRDX, 16 * 3); const Reg64& pz = sf.p[0]; @@ -1383,24 +1574,24 @@ private: const Reg64& t8 = sf.t[8]; const Reg64& t9 = sf.t[9]; - movq(xm0, pz); // save pz - mov(t7, (uint64_t)p); + vmovq(xm0, pz); // save pz + mov(t7, pL_); mov(t9, ptr [px]); mul3x1_sqr1(px, t9, t3, t2, t1, t0); mov(t0, rdx); - montgomery3_sub(pp, t0, t9, t2, t1, px, t3, t7, t4, t5, t6, t8, pz, true); + montgomery3_sub(rp_, t0, t9, t2, t1, px, t3, t7, t4, t5, t6, t8, pz, true); mov(t3, ptr [px + 8]); mul3x1_sqr2(px, t3, t6, t5, t4); add_rr(Pack(t1, t0, t9, t2), Pack(rdx, rax, t5, t4)); if (isFullBit_) setc(pz.cvt8()); - montgomery3_sub(pp, t1, t3, t9, t2, px, t0, t7, t4, t5, t6, t8, pz, false); + montgomery3_sub(rp_, t1, t3, t9, t2, px, t0, t7, t4, t5, t6, t8, pz, false); mov(t0, ptr [px + 16]); mul3x1_sqr3(t0, t5, t4); add_rr(Pack(t2, t1, t3, t9), Pack(rdx, rax, t5, t4)); if (isFullBit_) setc(pz.cvt8()); - montgomery3_sub(pp, t2, t0, t3, t9, px, t1, t7, t4, t5, t6, t8, pz, false); + montgomery3_sub(rp_, t2, t0, t3, t9, px, t1, t7, t4, t5, t6, t8, pz, false); // [t9:t2:t0:t3] mov(t4, t3); @@ -1411,18 +1602,17 @@ private: cmovc(t3, t4); cmovc(t0, t5); cmovc(t2, t6); - movq(pz, xm0); + vmovq(pz, xm0); store_mr(pz, Pack(t2, t0, t3)); } /* py[5..0] <- px[2..0]^2 - @note use rax, rdx, rcx! + @note use rax, rdx */ void sqrPre3(const RegExp& py, const RegExp& px, const Pack& t) { const Reg64& a = rax; const Reg64& d = rdx; - const Reg64& c = rcx; const Reg64& t0 = t[0]; const Reg64& t1 = t[1]; const Reg64& t2 = t[2]; @@ -1433,6 +1623,7 @@ private: const Reg64& t7 = t[7]; const Reg64& t8 = t[8]; const Reg64& t9 = t[9]; + const Reg64& t10 = t[10]; if (useMulx_) { mov(d, ptr [px + 8 * 0]); @@ -1453,7 +1644,7 @@ private: mov(d, t7); mulx(t8, t7, d); - mulx(c, t9, t9); + mulx(t10, t9, t9); } else { mov(t9, ptr [px + 8 * 0]); mov(a, t9); @@ -1484,11 +1675,11 @@ private: mov(a, ptr [px + 8 * 2]); mul(t9); mov(t9, a); - mov(c, d); + mov(t10, d); } add(t2, t7); adc(t8, t9); - mov(t7, c); + mov(t7, t10); adc(t7, 0); // [t7:t8:t2:t1] add(t0, t1); @@ -1500,7 +1691,7 @@ private: mov(a, ptr [px + 8 * 2]); mul(a); add(t4, t9); - adc(a, c); + adc(a, t10); adc(d, 0); // [d:a:t4:t3] add(t2, t3); @@ -1537,13 +1728,13 @@ private: const Reg64& a = rax; const Reg64& d = rdx; mov(d, ptr [px]); - mulx(hi, a, ptr [py + 8 * 0]); - adox(pd[0], a); - mov(ptr [pz], pd[0]); - for (size_t i = 1; i < pd.size(); i++) { - adcx(pd[i], hi); - mulx(hi, a, ptr [py + 8 * i]); + xor_(a, a); + for (size_t i = 0; i < pd.size(); i++) { + mulx(hi, a, ptr [py + i * 8]); adox(pd[i], a); + if (i == 0) mov(ptr[pz], pd[0]); + if (i == pd.size() - 1) break; + adcx(pd[i + 1], hi); } mov(d, 0); adcx(hi, d); @@ -1611,6 +1802,7 @@ private: if (useMulx_) { mulPack(pz, px, py, Pack(t2, t1, t0)); +#if 0 // a little slow if (useAdx_) { // [t2:t1:t0] mulPackAdd(pz + 8 * 1, px + 8 * 1, py, t3, Pack(t2, t1, t0)); @@ -1620,6 +1812,7 @@ private: store_mr(pz + 8 * 3, Pack(t4, t3, t2)); return; } +#endif } else { mov(t5, ptr [px]); mov(a, ptr [py + 8 * 0]); @@ -1749,6 +1942,7 @@ private: } /* py[7..0] = px[3..0] ^ 2 + use xmm0 */ void sqrPre4(const RegExp& py, const RegExp& px, const Pack& t) { @@ -1762,30 +1956,76 @@ private: const Reg64& t7 = t[7]; const Reg64& t8 = t[8]; const Reg64& t9 = t[9]; + const Reg64& t10 = t[10]; + const Reg64& a = rax; + const Reg64& d = rdx; - // (AN + B)^2 = A^2N^2 + 2AB + B^2 - - mul2x2(px + 8 * 0, px + 8 * 2, t4, t3, t2, t1, t0); - // [t3:t2:t1:t0] = AB - xor_(t4, t4); - add_rr(Pack(t4, t3, t2, t1, t0), Pack(t4, t3, t2, t1, t0)); - // [t4:t3:t2:t1:t0] = 2AB - store_mr(py + 8 * 2, Pack(t4, t3, t2, t1, t0)); - - mov(t8, ptr [px + 8 * 0]); - mov(t9, ptr [px + 8 * 1]); - sqr2(t1, t0, t7, t6, t9, t8, rax, rcx); - // B^2 = [t1:t0:t7:t6] - store_mr(py + 8 * 0, Pack(t7, t6)); - // [t1:t0] - - mov(t8, ptr [px + 8 * 2]); - mov(t9, ptr [px + 8 * 3]); - sqr2(t5, t4, t3, t2, t9, t8, rax, rcx); - // [t5:t4:t3:t2] - add_rm(Pack(t4, t3, t2, t1, t0), py + 8 * 2); - adc(t5, 0); - store_mr(py + 8 * 2, Pack(t5, t4, t3, t2, t1, t0)); + /* + (aN + b)^2 = a^2 N^2 + 2ab N + b^2 + */ + load_rm(Pack(t9, t8), px); + sqr2(t3, t2, t1, t0, t9, t8, t7, t6); + // [t3:t2:t1:t0] = b^2 + store_mr(py, Pack(t1, t0)); + vmovq(xm0, t2); + mul2x2(px, px + 2 * 8, t6, t5, t4, t1, t0); + // [t5:t4:t1:t0] = ab + xor_(t6, t6); + add_rr(Pack(t6, t5, t4, t1, t0), Pack(t6, t5, t4, t1, t0)); + // [t6:t5:t4:t1:t0] = 2ab + load_rm(Pack(t8, t7), px + 2 * 8); + // free t10, t9, rax, rdx + /* + [d:t8:t10:t9] = [t8:t7]^2 + */ + mov(d, t7); + mulx(t10, t9, t7); // [t10:t9] = t7^2 + mulx(t7, t2, t8); // [t7:t2] = t7 t8 + xor_(a, a); + add_rr(Pack(a, t7, t2), Pack(a, t7, t2)); + // [a:t7:t2] = 2 t7 t8 + mov(d, t8); + mulx(d, t8, t8); // [d:t8] = t8^2 + add_rr(Pack(d, t8, t10), Pack(a, t7, t2)); + // [d:t8:t10:t9] = [t8:t7]^2 + vmovq(t2, xm0); + add_rr(Pack(t8, t10, t9, t3, t2), Pack(t6, t5, t4, t1, t0)); + adc(d, 0); + store_mr(py + 2 * 8, Pack(d, t8, t10, t9, t3, t2)); + } + /* + py[11..0] = px[5..0] ^ 2 + use rax, rdx, stack[6 * 8] + */ + void sqrPre6(const RegExp& py, const RegExp& px, const Pack& t) + { + const Reg64& t0 = t[0]; + const Reg64& t1 = t[1]; + const Reg64& t2 = t[2]; + /* + (aN + b)^2 = a^2 N^2 + 2ab N + b^2 + */ + sqrPre3(py, px, t); // [py] <- b^2 + sqrPre3(py + 6 * 8, px + 3 * 8, t); // [py + 6 * 8] <- a^2 + mulPre3(rsp, px, px + 3 * 8, t); // ab + Pack ab = t.sub(0, 6); + load_rm(ab, rsp); + xor_(rax, rax); + for (int i = 0; i < 6; i++) { + if (i == 0) { + add(ab[i], ab[i]); + } else { + adc(ab[i], ab[i]); + } + } + adc(rax, rax); + add_rm(ab, py + 3 * 8); + store_mr(py + 3 * 8, ab); + load_rm(Pack(t2, t1, t0), py + 9 * 8); + adc(t0, rax); + adc(t1, 0); + adc(t2, 0); + store_mr(py + 9 * 8, Pack(t2, t1, t0)); } /* pz[7..0] <- px[3..0] * py[3..0] @@ -1805,6 +2045,16 @@ private: const Reg64& t8 = t[8]; const Reg64& t9 = t[9]; +#if 0 // a little slower + if (useMulx_ && useAdx_) { + mulPack(pz, px, py, Pack(t3, t2, t1, t0)); + mulPackAdd(pz + 8 * 1, px + 8 * 1, py, t4, Pack(t3, t2, t1, t0)); + mulPackAdd(pz + 8 * 2, px + 8 * 2, py, t0, Pack(t4, t3, t2, t1)); + mulPackAdd(pz + 8 * 3, px + 8 * 3, py, t1, Pack(t0, t4, t3, t2)); + store_mr(pz + 8 * 4, Pack(t1, t0, t4, t3)); + return; + } +#endif #if 0 // a little slower if (!useMulx_) { @@ -1818,28 +2068,17 @@ private: mul2x2(px + 8 * 0, py + 8 * 0, t9, t8, t7, t6, t5); store_mr(pz, Pack(t6, t5)); // [t8:t7] - movq(xm0, t7); - movq(xm1, t8); + vmovq(xm0, t7); + vmovq(xm1, t8); mul2x2(px + 8 * 2, py + 8 * 2, t8, t7, t9, t6, t5); - movq(a, xm0); - movq(d, xm1); + vmovq(a, xm0); + vmovq(d, xm1); add_rr(Pack(t4, t3, t2, t1, t0), Pack(t9, t6, t5, d, a)); adc(t7, 0); store_mr(pz + 8 * 2, Pack(t7, t4, t3, t2, t1, t0)); #else if (useMulx_) { mulPack(pz, px, py, Pack(t3, t2, t1, t0)); - if (0 && useAdx_) { // a little slower? - // [t3:t2:t1:t0] - mulPackAdd(pz + 8 * 1, px + 8 * 1, py, t4, Pack(t3, t2, t1, t0)); - // [t4:t3:t2:t1] - mulPackAdd(pz + 8 * 2, px + 8 * 2, py, t5, Pack(t4, t3, t2, t1)); - // [t5:t4:t3:t2] - mulPackAdd(pz + 8 * 3, px + 8 * 3, py, t0, Pack(t5, t4, t3, t2)); - // [t0:t5:t4:t3] - store_mr(pz + 8 * 4, Pack(t0, t5, t4, t3)); - return; - } } else { mov(t5, ptr [px]); mov(a, ptr [py + 8 * 0]); @@ -1894,12 +2133,111 @@ private: mov(ptr [pz + 8 * 7], d); #endif } - void mulPre6(const RegExp& pz, const RegExp& px, const RegExp& py, const Pack& t) + // [gp0] <- [gp1] * [gp2] + void mulPre6(const Pack& t) { + const Reg64& pz = gp0; + const Reg64& px = gp1; + const Reg64& py = gp2; const Reg64& t0 = t[0]; const Reg64& t1 = t[1]; const Reg64& t2 = t[2]; const Reg64& t3 = t[3]; +#if 0 // slower than basic multiplication(56clk -> 67clk) +// const Reg64& t7 = t[7]; +// const Reg64& t8 = t[8]; +// const Reg64& t9 = t[9]; + const Reg64& a = rax; + const Reg64& d = rdx; + const int stackSize = (3 + 3 + 6 + 1 + 1 + 1) * 8; // a+b, c+d, (a+b)(c+d), x, y, z + const int abPos = 0; + const int cdPos = abPos + 3 * 8; + const int abcdPos = cdPos + 3 * 8; + const int zPos = abcdPos + 6 * 8; + const int yPos = zPos + 8; + const int xPos = yPos + 8; + + sub(rsp, stackSize); + mov(ptr[rsp + zPos], pz); + mov(ptr[rsp + xPos], px); + mov(ptr[rsp + yPos], py); + /* + x = aN + b, y = cN + d + xy = abN^2 + ((a+b)(c+d) - ac - bd)N + bd + */ + xor_(a, a); + load_rm(Pack(t2, t1, t0), px); // b + add_rm(Pack(t2, t1, t0), px + 3 * 8); // a + b + adc(a, 0); + store_mr(pz, Pack(t2, t1, t0)); + vmovq(xm0, a); // carry1 + + xor_(a, a); + load_rm(Pack(t2, t1, t0), py); // d + add_rm(Pack(t2, t1, t0), py + 3 * 8); // c + d + adc(a, 0); + store_mr(pz + 3 * 8, Pack(t2, t1, t0)); + vmovq(xm1, a); // carry2 + + mulPre3(rsp + abcdPos, pz, pz + 3 * 8, t); // (a+b)(c+d) + + vmovq(a, xm0); + vmovq(d, xm1); + mov(t3, a); + and_(t3, d); // t3 = carry1 & carry2 + Label doNothing; + je(doNothing); + load_rm(Pack(t2, t1, t0), rsp + abcdPos + 3 * 8); + test(a, a); + je("@f"); + // add (c+d) + add_rm(Pack(t2, t1, t0), pz + 3 * 8); + adc(t3, 0); + L("@@"); + test(d, d); + je("@f"); + // add(a+b) + add_rm(Pack(t2, t1, t0), pz); + adc(t3, 0); + L("@@"); + store_mr(rsp + abcdPos + 3 * 8, Pack(t2, t1, t0)); + L(doNothing); + vmovq(xm0, t3); // save new carry + + + mov(gp0, ptr [rsp + zPos]); + mov(gp1, ptr [rsp + xPos]); + mov(gp2, ptr [rsp + yPos]); + mulPre3(gp0, gp1, gp2, t); // [rsp] <- bd + + mov(gp0, ptr [rsp + zPos]); + mov(gp1, ptr [rsp + xPos]); + mov(gp2, ptr [rsp + yPos]); + mulPre3(gp0 + 6 * 8, gp1 + 3 * 8, gp2 + 3 * 8, t); // [rsp + 6 * 8] <- ac + + mov(pz, ptr[rsp + zPos]); + vmovq(d, xm0); + for (int i = 0; i < 6; i++) { + mov(a, ptr[pz + (3 + i) * 8]); + if (i == 0) { + add(a, ptr[rsp + abcdPos + i * 8]); + } else { + adc(a, ptr[rsp + abcdPos + i * 8]); + } + mov(ptr[pz + (3 + i) * 8], a); + } + mov(a, ptr[pz + 9 * 8]); + adc(a, d); + mov(ptr[pz + 9 * 8], a); + jnc("@f"); + for (int i = 10; i < 12; i++) { + mov(a, ptr[pz + i * 8]); + adc(a, 0); + mov(ptr[pz + i * 8], a); + } + L("@@"); + add(rsp, stackSize); +#else const Reg64& t4 = t[4]; const Reg64& t5 = t[5]; const Reg64& t6 = t[6]; @@ -1911,6 +2249,7 @@ private: mulPackAdd(pz + 8 * 4, px + 8 * 4, py, t2, Pack(t1, t0, t6, t5, t4, t3)); // [t2:t1:t0:t6:t5:t4] mulPackAdd(pz + 8 * 5, px + 8 * 5, py, t3, Pack(t2, t1, t0, t6, t5, t4)); // [t3:t2:t1:t0:t6:t5] store_mr(pz + 8 * 6, Pack(t3, t2, t1, t0, t6, t5)); +#endif } /* @input (z, xy) @@ -1934,11 +2273,11 @@ private: const Reg64& a = rax; const Reg64& d = rdx; - movq(xm0, z); + vmovq(xm0, z); mov(z, ptr [xy + 0 * 8]); mov(a, rp_); mul(z); - lea(t0, ptr [rip + *pL_]); + lea(t0, ptr [rip + pL_]); load_rm(Pack(t7, t6, t5, t4, t3, t2, t1), xy); mov(d, a); // q mulPackAddShr(Pack(t7, t6, t5, t4, t3, t2, t1), t0, t10); @@ -1951,32 +2290,32 @@ private: // z = [t1:t0:t10:t9:t8:t7:t6:t5:t4:t3:t2] mov(a, rp_); mul(t2); - movq(xm1, t0); // save - lea(t0, ptr [rip + *pL_]); + vmovq(xm1, t0); // save + lea(t0, ptr [rip + pL_]); mov(d, a); - movq(xm2, t10); + vmovq(xm2, t10); mulPackAddShr(Pack(t8, t7, t6, t5, t4, t3, t2), t0, t10); - movq(t10, xm2); + vmovq(t10, xm2); adc(t9, rax); adc(t10, rax); - movq(t0, xm1); // load + vmovq(t0, xm1); // load adc(t0, rax); adc(t1, rax); // z = [t1:t0:t10:t9:t8:t7:t6:t5:t4:t3] mov(a, rp_); mul(t3); - lea(t2, ptr [rip + *pL_]); + lea(t2, ptr [rip + pL_]); mov(d, a); - movq(xm2, t10); + vmovq(xm2, t10); mulPackAddShr(Pack(t9, t8, t7, t6, t5, t4, t3), t2, t10); - movq(t10, xm2); + vmovq(t10, xm2); adc(t10, rax); adc(t0, rax); adc(t1, rax); // z = [t1:t0:t10:t9:t8:t7:t6:t5:t4] mov(a, rp_); mul(t4); - lea(t2, ptr [rip + *pL_]); + lea(t2, ptr [rip + pL_]); mov(d, a); mulPackAddShr(Pack(t10, t9, t8, t7, t6, t5, t4), t2, t3); adc(t0, rax); @@ -1984,14 +2323,14 @@ private: // z = [t1:t0:t10:t9:t8:t7:t6:t5] mov(a, rp_); mul(t5); - lea(t2, ptr [rip + *pL_]); + lea(t2, ptr [rip + pL_]); mov(d, a); mulPackAddShr(Pack(t0, t10, t9, t8, t7, t6, t5), t2, t3); adc(t1, a); // z = [t1:t0:t10:t9:t8:t7:t6] mov(a, rp_); mul(t6); - lea(t2, ptr [rip + *pL_]); + lea(t2, ptr [rip + pL_]); mov(d, a); mulPackAddShr(Pack(t1, t0, t10, t9, t8, t7, t6), t2, t3, true); // z = [t1:t0:t10:t9:t8:t7] @@ -2000,47 +2339,87 @@ private: mov_rr(keep, zp); sub_rm(zp, t2); // z -= p cmovc_rr(zp, keep); - movq(z, xm0); + vmovq(z, xm0); store_mr(z, zp); } - void gen_fpDbl_sqrPre(mcl::fp::Op& op) + void2u gen_fpDbl_sqrPre() { - if (useMulx_ && pn_ == 2) { + align(16); + void2u func = getCurr<void2u>(); + if (pn_ == 2 && useMulx_) { StackFrame sf(this, 2, 7 | UseRDX); sqrPre2(sf.p[0], sf.p[1], sf.t); - return; + return func; } if (pn_ == 3) { - StackFrame sf(this, 2, 10 | UseRDX | UseRCX); - sqrPre3(sf.p[0], sf.p[1], sf.t); - return; + StackFrame sf(this, 3, 10 | UseRDX); + Pack t = sf.t; + t.append(sf.p[2]); + sqrPre3(sf.p[0], sf.p[1], t); + return func; } - if (useMulx_ && pn_ == 4) { - StackFrame sf(this, 2, 10 | UseRDX | UseRCX); - sqrPre4(sf.p[0], sf.p[1], sf.t); - return; + if (pn_ == 4 && useMulx_) { + StackFrame sf(this, 3, 10 | UseRDX); + Pack t = sf.t; + t.append(sf.p[2]); + sqrPre4(sf.p[0], sf.p[1], t); + return func; + } + if (pn_ == 6 && useMulx_ && useAdx_) { + StackFrame sf(this, 3, 10 | UseRDX, 6 * 8); + Pack t = sf.t; + t.append(sf.p[2]); + sqrPre6(sf.p[0], sf.p[1], t); + return func; } + return 0; +#if 0 #ifdef XBYAK64_WIN mov(r8, rdx); #else mov(rdx, rsi); #endif jmp((void*)op.fpDbl_mulPreA_); + return func; +#endif } - void gen_fpDbl_mulPre() + void3u gen_fpDbl_mulPre() { - if (useMulx_ && pn_ == 2) { + align(16); + void3u func = getCurr<void3u>(); + if (pn_ == 2 && useMulx_) { StackFrame sf(this, 3, 5 | UseRDX); mulPre2(sf.p[0], sf.p[1], sf.p[2], sf.t); - return; + return func; } if (pn_ == 3) { StackFrame sf(this, 3, 10 | UseRDX); mulPre3(sf.p[0], sf.p[1], sf.p[2], sf.t); - return; + return func; } - assert(0); - exit(1); + if (pn_ == 4) { + /* + fpDbl_mulPre is available as C function + this function calls mulPreL directly. + */ + StackFrame sf(this, 3, 10 | UseRDX, 0, false); + mulPre4(gp0, gp1, gp2, sf.t); + sf.close(); // make epilog + L(mulPreL); // called only from asm code + mulPre4(gp0, gp1, gp2, sf.t); + ret(); + return func; + } + if (pn_ == 6 && useAdx_) { + StackFrame sf(this, 3, 10 | UseRDX, 0, false); + call(mulPreL); + sf.close(); // make epilog + L(mulPreL); // called only from asm code + mulPre6(sf.t); + ret(); + return func; + } + return 0; } static inline void debug_put_inner(const uint64_t *ptr, int n) { @@ -2250,10 +2629,10 @@ private: { if (n >= 10) exit(1); static uint64_t buf[10]; - movq(xm0, rax); + vmovq(xm0, rax); mov(rax, (size_t)buf); store_mp(rax, mp, t); - movq(rax, xm0); + vmovq(rax, xm0); push(rax); mov(rax, (size_t)buf); debug_put(rax, n); @@ -2270,11 +2649,8 @@ private: */ void gen_preInv() { - assert(pn_ >= 1); + assert(1 <= pn_ && pn_ <= 4); const int freeRegNum = 13; - if (pn_ > 9) { - throw cybozu::Exception("mcl:FpGenerator:gen_preInv:large pn_") << pn_; - } StackFrame sf(this, 2, 10 | UseRDX | UseRCX, (std::max<int>(0, pn_ * 5 - freeRegNum) + 1 + (isFullBit_ ? 1 : 0)) * 8); const Reg64& pr = sf.p[0]; const Reg64& px = sf.p[1]; @@ -2307,7 +2683,7 @@ private: mov(rax, px); // px is free frome here load_mp(vv, rax, t); // v = x - mov(rax, (size_t)p_); + mov(rax, pL_); load_mp(uu, rax, t); // u = p_ // k = 0 xor_(rax, rax); @@ -2324,46 +2700,6 @@ private: } else { mov(qword [ss.getMem(0)], 1); } -#if 0 - L(".lp"); - or_mp(vv, t); - jz(".exit", T_NEAR); - - g_test(uu[0], 1); - jz(".u_even", T_NEAR); - g_test(vv[0], 1); - jz(".v_even", T_NEAR); - for (int i = pn_ - 1; i >= 0; i--) { - g_cmp(vv[i], uu[i], t); - jc(".v_lt_u", T_NEAR); - if (i > 0) jnz(".v_ge_u", T_NEAR); - } - - L(".v_ge_u"); - sub_mp(vv, uu, t); - add_mp(ss, rr, t); - L(".v_even"); - shr_mp(vv, 1, t); - twice_mp(rr, t); - if (isFullBit_) { - sbb(t, t); - mov(ptr [rTop], t); - } - inc(rax); - jmp(".lp", T_NEAR); - L(".v_lt_u"); - sub_mp(uu, vv, t); - add_mp(rr, ss, t); - if (isFullBit_) { - sbb(t, t); - mov(ptr [rTop], t); - } - L(".u_even"); - shr_mp(uu, 1, t); - twice_mp(ss, t); - inc(rax); - jmp(".lp", T_NEAR); -#else for (int cn = pn_; cn > 0; cn--) { const std::string _lp = mkLabel(".lp", cn); const std::string _u_v_odd = mkLabel(".u_v_odd", cn); @@ -2420,13 +2756,12 @@ private: uu.removeLast(); } } -#endif L(".exit"); assert(ss.isReg(0)); const Reg64& t2 = ss.getReg(0); const Reg64& t3 = rdx; - mov(t2, (size_t)p_); + mov(t2, pL_); if (isFullBit_) { mov(t, ptr [rTop]); test(t, t); @@ -3057,7 +3392,7 @@ private: mul4x1(px, y, t3, t2, t1, t0, t4); // [rdx:y:t2:t1:t0] = px[3..0] * y if (isFullBit_) { - movq(xt, px); + vmovq(xt, px); xor_(px, px); } add_rr(Pack(c4, y, c2, c1, c0), Pack(rdx, c3, t2, t1, t0)); @@ -3081,13 +3416,19 @@ private: adc(c0, 0); } else { adc(c0, px); - movq(px, xt); + vmovq(px, xt); } } } - void gen_fp2Dbl_mulPre(Label& mulPreL) + void3u gen_fp2Dbl_mulPre() { - assert(!isFullBit_); + if (isFullBit_) return 0; +// if (pn_ != 4 && !(pn_ == 6 && useMulx_ && useAdx_)) return 0; + // almost same for pn_ == 6 + if (pn_ != 4) return 0; + align(16); + void3u func = getCurr<void3u>(); + const RegExp z = rsp + 0 * 8; const RegExp x = rsp + 1 * 8; const RegExp y = rsp + 2 * 8; @@ -3100,9 +3441,9 @@ private: mov(ptr [x], gp1); mov(ptr [y], gp2); // s = a + b - gen_raw_add(s, gp1, gp1 + FpByte_, rax, 4); + gen_raw_add(s, gp1, gp1 + FpByte_, rax, pn_); // t = c + d - gen_raw_add(t, gp2, gp2 + FpByte_, rax, 4); + gen_raw_add(t, gp2, gp2 + FpByte_, rax, pn_); // d1 = (a + b)(c + d) mov(gp0, ptr [z]); add(gp0, FpByte_ * 2); // d1 @@ -3127,20 +3468,33 @@ private: add(gp0, FpByte_ * 2); // d1 mov(gp1, gp0); mov(gp2, ptr [z]); - gen_raw_sub(gp0, gp1, gp2, rax, 8); + gen_raw_sub(gp0, gp1, gp2, rax, pn_ * 2); lea(gp2, ptr [d2]); - gen_raw_sub(gp0, gp1, gp2, rax, 8); + gen_raw_sub(gp0, gp1, gp2, rax, pn_ * 2); mov(gp0, ptr [z]); mov(gp1, gp0); lea(gp2, ptr [d2]); - gen_raw_sub(gp0, gp1, gp2, rax, 4); - gen_raw_fp_sub(gp0 + 8 * 4, gp1 + 8 * 4, gp2 + 8 * 4, Pack(gt0, gt1, gt2, gt3, gt4, gt5, gt6, gt7), true); + gen_raw_sub(gp0, gp1, gp2, rax, pn_); + if (pn_ == 4) { + gen_raw_fp_sub(gp0 + pn_ * 8, gp1 + pn_ * 8, gp2 + pn_ * 8, Pack(gt0, gt1, gt2, gt3, gt4, gt5, gt6, gt7), true); + } else { + assert(pn_ == 6); + gen_raw_fp_sub6(gp0, gp1, gp2, pn_ * 8, sf.t.sub(0, 6), true); + } + return func; } - void gen_fp2Dbl_sqrPre(Label& mulPreL) + void2u gen_fp2Dbl_sqrPre() { - assert(!isFullBit_); + if (isFullBit_) return 0; +// if (pn_ != 4 && !(pn_ == 6 && useMulx_ && useAdx_)) return 0; + // almost same for pn_ == 6 + if (pn_ != 4) return 0; + align(16); + void2u func = getCurr<void2u>(); + // almost same for pn_ == 6 + if (pn_ != 4) return 0; const RegExp y = rsp + 0 * 8; const RegExp x = rsp + 1 * 8; const Ext1 t1(FpByte_, rsp, 2 * 8); @@ -3149,10 +3503,15 @@ private: StackFrame sf(this, 3 /* not 2 */, 10 | UseRDX, t2.next); mov(ptr [y], gp0); mov(ptr [x], gp1); - const Pack a = sf.t.sub(0, 4); - const Pack b = sf.t.sub(4, 4); + Pack t = sf.t; + if (pn_ == 6) { + t.append(rax); + t.append(rdx); + } + const Pack a = t.sub(0, pn_); + const Pack b = t.sub(pn_, pn_); load_rm(b, gp1 + FpByte_); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < pn_; i++) { mov(rax, b[i]); if (i == 0) { add(rax, rax); @@ -3170,11 +3529,17 @@ private: mov(gp2, ptr [x]); call(mulPreL); mov(gp0, ptr [x]); - gen_raw_fp_sub(t1, gp0, gp0 + FpByte_, sf.t, false); + if (pn_ == 4) { + gen_raw_fp_sub(t1, gp0, gp0 + FpByte_, sf.t, false); + } else { + assert(pn_ == 6); + gen_raw_fp_sub6(t1, gp0, gp0, FpByte_, a, false); + } mov(gp0, ptr [y]); lea(gp1, ptr [t1]); lea(gp2, ptr [t2]); call(mulPreL); + return func; } void gen_fp2_add4() { @@ -3183,6 +3548,61 @@ private: gen_raw_fp_add(sf.p[0], sf.p[1], sf.p[2], sf.t, false); gen_raw_fp_add(sf.p[0] + FpByte_, sf.p[1] + FpByte_, sf.p[2] + FpByte_, sf.t, false); } + void gen_fp2_add6() + { + assert(!isFullBit_); + StackFrame sf(this, 3, 10); + const Reg64& pz = sf.p[0]; + const Reg64& px = sf.p[1]; + const Reg64& py = sf.p[2]; + Pack t1 = sf.t.sub(0, 6); + Pack t2 = sf.t.sub(6); + t2.append(rax); + t2.append(px); // destory after used + vmovq(xm0, px); + gen_raw_fp_add6(pz, px, py, t1, t2, false); + vmovq(px, xm0); + gen_raw_fp_add6(pz + FpByte_, px + FpByte_, py + FpByte_, t1, t2, false); + } + void gen_fp2_sub6() + { + StackFrame sf(this, 3, 5); + const Reg64& pz = sf.p[0]; + const Reg64& px = sf.p[1]; + const Reg64& py = sf.p[2]; + Pack t = sf.t; + t.append(rax); + gen_raw_fp_sub6(pz, px, py, 0, t, false); + gen_raw_fp_sub6(pz, px, py, FpByte_, t, false); + } + void3u gen_fp2_add() + { + align(16); + void3u func = getCurr<void3u>(); + if (pn_ == 4 && !isFullBit_) { + gen_fp2_add4(); + return func; + } + if (pn_ == 6 && !isFullBit_) { + gen_fp2_add6(); + return func; + } + return 0; + } + void3u gen_fp2_sub() + { + align(16); + void3u func = getCurr<void3u>(); + if (pn_ == 4 && !isFullBit_) { + gen_fp2_sub4(); + return func; + } + if (pn_ == 6 && !isFullBit_) { + gen_fp2_sub6(); + return func; + } + return 0; + } void gen_fp2_sub4() { assert(!isFullBit_); @@ -3198,14 +3618,17 @@ private: void gen_fp2_mul_xi4() { assert(!isFullBit_); -#if 0 - StackFrame sf(this, 2, 10 | UseRDX | UseRCX); + StackFrame sf(this, 2, 11 | UseRDX); + const Reg64& py = sf.p[0]; + const Reg64& px = sf.p[1]; Pack a = sf.t.sub(0, 4); Pack b = sf.t.sub(4, 4); - Pack t(rdx, rcx, sf.t[8], sf.t[9]); - load_rm(a, sf.p[1]); - load_rm(b, sf.p[1] + FpByte_); - for (int i = 0; i < 4; i++) { + Pack t = sf.t.sub(8); + t.append(rdx); + assert(t.size() == 4); + load_rm(a, px); + load_rm(b, px + FpByte_); + for (int i = 0; i < pn_; i++) { mov(t[i], a[i]); if (i == 0) { add(t[i], b[i]); @@ -3214,41 +3637,78 @@ private: } } sub_rr(a, b); - mov(rax, (size_t)p_); + mov(rax, pL_); load_rm(b, rax); sbb(rax, rax); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < pn_; i++) { and_(b[i], rax); } add_rr(a, b); - store_mr(sf.p[0], a); - mov(rax, (size_t)p_); + store_mr(py, a); + mov(rax, pL_); mov_rr(a, t); sub_rm(t, rax); - for (int i = 0; i < 4; i++) { - cmovc(t[i], a[i]); + cmovc_rr(t, a); + store_mr(py + FpByte_, t); + } + void gen_fp2_mul_xi6() + { + assert(!isFullBit_); + StackFrame sf(this, 2, 12); + const Reg64& py = sf.p[0]; + const Reg64& px = sf.p[1]; + Pack a = sf.t.sub(0, 6); + Pack b = sf.t.sub(6); + load_rm(a, px); + mov_rr(b, a); + add_rm(b, px + FpByte_); + sub_rm(a, px + FpByte_); + mov(rax, pL_); + jnc("@f"); + add_rm(a, rax); + L("@@"); + store_mr(py, a); + mov_rr(a, b); + sub_rm(b, rax); + cmovc_rr(b, a); + store_mr(py + FpByte_, b); + } + void2u gen_fp2_mul_xi() + { + if (isFullBit_) return 0; + if (op_->xi_a != 1) return 0; + align(16); + void2u func = getCurr<void2u>(); + if (pn_ == 4) { + gen_fp2_mul_xi4(); + return func; } - store_mr(sf.p[0] + FpByte_, t); -#else - StackFrame sf(this, 2, 8, 8 * 4); - gen_raw_fp_add(rsp, sf.p[1], sf.p[1] + FpByte_, sf.t, false); - gen_raw_fp_sub(sf.p[0], sf.p[1], sf.p[1] + FpByte_, sf.t, false); - for (int i = 0; i < 4; i++) { - mov(rax, ptr [rsp + i * 8]); - mov(ptr[sf.p[0] + FpByte_ + i * 8], rax); + if (pn_ == 6) { + gen_fp2_mul_xi6(); + return func; } -#endif + return 0; } - void gen_fp2_neg4() + void2u gen_fp2_neg() { - assert(!isFullBit_); - StackFrame sf(this, 2, UseRDX | pn_); - gen_raw_neg(sf.p[0], sf.p[1], sf.t); - gen_raw_neg(sf.p[0] + FpByte_, sf.p[1] + FpByte_, sf.t); + align(16); + void2u func = getCurr<void2u>(); + if (pn_ <= 6) { + StackFrame sf(this, 2, UseRDX | pn_); + gen_raw_neg(sf.p[0], sf.p[1], sf.t); + gen_raw_neg(sf.p[0] + FpByte_, sf.p[1] + FpByte_, sf.t); + return func; + } + return 0; } - void gen_fp2_mul4(Label& fpDbl_modL) + void3u gen_fp2_mul() { - assert(!isFullBit_); + if (isFullBit_) return 0; + if (pn_ != 4 && !(pn_ == 6 && useMulx_ && useAdx_)) return 0; + align(16); + void3u func = getCurr<void3u>(); + bool embedded = pn_ == 4; + const RegExp z = rsp + 0 * 8; const RegExp x = rsp + 1 * 8; const RegExp y = rsp + 2 * 8; @@ -3263,27 +3723,50 @@ private: mov(ptr[x], gp1); mov(ptr[y], gp2); // s = a + b - gen_raw_add(s, gp1, gp1 + FpByte_, rax, 4); + gen_raw_add(s, gp1, gp1 + FpByte_, rax, pn_); // t = c + d - gen_raw_add(t, gp2, gp2 + FpByte_, rax, 4); + gen_raw_add(t, gp2, gp2 + FpByte_, rax, pn_); // d1 = (a + b)(c + d) - mulPre4(d1, s, t, sf.t); + if (embedded) { + mulPre4(d1, s, t, sf.t); + } else { + lea(gp0, ptr [d1]); + lea(gp1, ptr [s]); + lea(gp2, ptr [t]); + call(mulPreL); + } // d0 = a c mov(gp1, ptr [x]); mov(gp2, ptr [y]); - mulPre4(d0, gp1, gp2, sf.t); + if (embedded) { + mulPre4(d0, gp1, gp2, sf.t); + } else { + lea(gp0, ptr [d0]); + call(mulPreL); + } // d2 = b d mov(gp1, ptr [x]); add(gp1, FpByte_); mov(gp2, ptr [y]); add(gp2, FpByte_); - mulPre4(d2, gp1, gp2, sf.t); + if (embedded) { + mulPre4(d2, gp1, gp2, sf.t); + } else { + lea(gp0, ptr [d2]); + call(mulPreL); + } - gen_raw_sub(d1, d1, d0, rax, 8); - gen_raw_sub(d1, d1, d2, rax, 8); + gen_raw_sub(d1, d1, d0, rax, pn_ * 2); + gen_raw_sub(d1, d1, d2, rax, pn_ * 2); - gen_raw_sub(d0, d0, d2, rax, 4); - gen_raw_fp_sub((RegExp)d0 + 8 * 4, (RegExp)d0 + 8 * 4, (RegExp)d2 + 8 * 4, Pack(gt0, gt1, gt2, gt3, gt4, gt5, gt6, gt7), true); + gen_raw_sub(d0, d0, d2, rax, pn_); + if (pn_ == 4) { + gen_raw_fp_sub((RegExp)d0 + pn_ * 8, (RegExp)d0 + pn_ * 8, (RegExp)d2 + pn_ * 8, Pack(gt0, gt1, gt2, gt3, gt4, gt5, gt6, gt7), true); + } else { + lea(gp0, ptr[d0]); + lea(gp2, ptr[d2]); + gen_raw_fp_sub6(gp0, gp0, gp2, pn_ * 8, sf.t.sub(0, 6), true); + } mov(gp0, ptr [z]); lea(gp1, ptr[d0]); @@ -3293,10 +3776,15 @@ private: add(gp0, FpByte_); lea(gp1, ptr[d1]); call(fpDbl_modL); + return func; } - void gen_fp2_sqr4(Label& fp_mulL) + void2u gen_fp2_sqr() { - assert(!isFullBit_); + if (isFullBit_) return 0; + if (pn_ != 4 && !(pn_ == 6 && useMulx_ && useAdx_)) return 0; + align(16); + void2u func = getCurr<void2u>(); + const RegExp y = rsp + 0 * 8; const RegExp x = rsp + 1 * 8; const Ext1 t1(FpByte_, rsp, 2 * 8); @@ -3309,7 +3797,7 @@ private: // t1 = b + b lea(gp0, ptr [t1]); if (nocarry) { - for (int i = 0; i < 4; i++) { + for (int i = 0; i < pn_; i++) { mov(rax, ptr [gp1 + FpByte_ + i * 8]); if (i == 0) { add(rax, rax); @@ -3319,7 +3807,15 @@ private: mov(ptr [gp0 + i * 8], rax); } } else { - gen_raw_fp_add(gp0, gp1 + FpByte_, gp1 + FpByte_, sf.t, false); + if (pn_ == 4) { + gen_raw_fp_add(gp0, gp1 + FpByte_, gp1 + FpByte_, sf.t, false); + } else { + assert(pn_ == 6); + Pack t = sf.t.sub(6, 4); + t.append(rax); + t.append(rdx); + gen_raw_fp_add6(gp0, gp1 + FpByte_, gp1 + FpByte_, sf.t.sub(0, 6), t, false); + } } // t1 = 2ab mov(gp1, gp0); @@ -3327,13 +3823,16 @@ private: call(fp_mulL); if (nocarry) { - Pack a = sf.t.sub(0, 4); - Pack b = sf.t.sub(4, 4); + Pack t = sf.t; + t.append(rdx); + t.append(gp1); + Pack a = t.sub(0, pn_); + Pack b = t.sub(pn_, pn_); mov(gp0, ptr [x]); load_rm(a, gp0); load_rm(b, gp0 + FpByte_); // t2 = a + b - for (int i = 0; i < 4; i++) { + for (int i = 0; i < pn_; i++) { mov(rax, a[i]); if (i == 0) { add(rax, b[i]); @@ -3343,14 +3842,24 @@ private: mov(ptr [(RegExp)t2 + i * 8], rax); } // t3 = a + p - b - mov(gp1, (size_t)p_); - add_rm(a, gp1); + mov(rax, pL_); + add_rm(a, rax); sub_rr(a, b); store_mr(t3, a); } else { mov(gp0, ptr [x]); - gen_raw_fp_add(t2, gp0, gp0 + FpByte_, sf.t, false); - gen_raw_fp_sub(t3, gp0, gp0 + FpByte_, sf.t, false); + if (pn_ == 4) { + gen_raw_fp_add(t2, gp0, gp0 + FpByte_, sf.t, false); + gen_raw_fp_sub(t3, gp0, gp0 + FpByte_, sf.t, false); + } else { + assert(pn_ == 6); + Pack p1 = sf.t.sub(0, 6); + Pack p2 = sf.t.sub(6, 4); + p2.append(rax); + p2.append(rdx); + gen_raw_fp_add6(t2, gp0, gp0 + FpByte_, p1, p2, false); + gen_raw_fp_sub6(t3, gp0, gp0 + FpByte_, 0, p1, false); + } } mov(gp0, ptr [y]); @@ -3358,10 +3867,11 @@ private: lea(gp2, ptr [t3]); call(fp_mulL); mov(gp0, ptr [y]); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < pn_; i++) { mov(rax, ptr [(RegExp)t1 + i * 8]); mov(ptr [gp0 + FpByte_ + i * 8], rax); } + return func; } }; diff --git a/vendor/github.com/dexon-foundation/mcl/src/she_c_impl.hpp b/vendor/github.com/dexon-foundation/mcl/src/she_c_impl.hpp index 723765a3c..073bc2b34 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/she_c_impl.hpp +++ b/vendor/github.com/dexon-foundation/mcl/src/she_c_impl.hpp @@ -5,7 +5,7 @@ #include <iosfwd> #include <stdint.h> #include <memory.h> -#include "../src/bn_c_impl.hpp" +#include "mcl/impl/bn_c_impl.hpp" #define MCLSHE_DLL_EXPORT #include <mcl/she.h> diff --git a/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak.h b/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak.h index 47494ef09..bcfeb34bf 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak.h +++ b/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak.h @@ -40,6 +40,8 @@ // This covers -std=(gnu|c)++(0x|11|1y), -stdlib=libc++, and modern Microsoft. #if ((defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(_LIBCPP_VERSION) ||\ ((__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__))) + #include <unordered_set> + #define XBYAK_STD_UNORDERED_SET std::unordered_set #include <unordered_map> #define XBYAK_STD_UNORDERED_MAP std::unordered_map #define XBYAK_STD_UNORDERED_MULTIMAP std::unordered_multimap @@ -49,16 +51,22 @@ libstdcxx 20070719 (from GCC 4.2.1, the last GPL 2 version). */ #elif XBYAK_GNUC_PREREQ(4, 5) || (XBYAK_GNUC_PREREQ(4, 2) && __GLIBCXX__ >= 20070719) || defined(__INTEL_COMPILER) || defined(__llvm__) + #include <tr1/unordered_set> + #define XBYAK_STD_UNORDERED_SET std::tr1::unordered_set #include <tr1/unordered_map> #define XBYAK_STD_UNORDERED_MAP std::tr1::unordered_map #define XBYAK_STD_UNORDERED_MULTIMAP std::tr1::unordered_multimap #elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER < 1600) + #include <unordered_set> + #define XBYAK_STD_UNORDERED_SET std::tr1::unordered_set #include <unordered_map> #define XBYAK_STD_UNORDERED_MAP std::tr1::unordered_map #define XBYAK_STD_UNORDERED_MULTIMAP std::tr1::unordered_multimap #else + #include <set> + #define XBYAK_STD_UNORDERED_SET std::set #include <map> #define XBYAK_STD_UNORDERED_MAP std::map #define XBYAK_STD_UNORDERED_MULTIMAP std::multimap @@ -105,7 +113,7 @@ namespace Xbyak { enum { DEFAULT_MAX_CODE_SIZE = 4096, - VERSION = 0x5730 /* 0xABCD = A.BC(D) */ + VERSION = 0x5751 /* 0xABCD = A.BC(D) */ }; #ifndef MIE_INTEGER_TYPE_DEFINED @@ -925,10 +933,10 @@ public: void dq(uint64 code) { db(code, 8); } const uint8 *getCode() const { return top_; } template<class F> - const F getCode() const { return CastTo<F>(top_); } + const F getCode() const { return reinterpret_cast<F>(top_); } const uint8 *getCurr() const { return &top_[size_]; } template<class F> - const F getCurr() const { return CastTo<F>(&top_[size_]); } + const F getCurr() const { return reinterpret_cast<F>(&top_[size_]); } size_t getSize() const { return size_; } void setSize(size_t size) { @@ -1134,6 +1142,7 @@ public: Label(const Label& rhs); Label& operator=(const Label& rhs); ~Label(); + void clear() { mgr = 0; id = 0; } int getId() const { return id; } const uint8 *getAddress() const; @@ -1172,6 +1181,7 @@ class LabelManager { }; typedef XBYAK_STD_UNORDERED_MAP<int, ClabelVal> ClabelDefList; typedef XBYAK_STD_UNORDERED_MULTIMAP<int, const JmpLabel> ClabelUndefList; + typedef XBYAK_STD_UNORDERED_SET<Label*> LabelPtrList; CodeArray *base_; // global : stateList_.front(), local : stateList_.back() @@ -1179,6 +1189,7 @@ class LabelManager { mutable int labelId_; ClabelDefList clabelDefList_; ClabelUndefList clabelUndefList_; + LabelPtrList labelPtrList_; int getId(const Label& label) const { @@ -1227,9 +1238,14 @@ class LabelManager { return true; } friend class Label; - void incRefCount(int id) { clabelDefList_[id].refCount++; } - void decRefCount(int id) + void incRefCount(int id, Label *label) { + clabelDefList_[id].refCount++; + labelPtrList_.insert(label); + } + void decRefCount(int id, Label *label) + { + labelPtrList_.erase(label); ClabelDefList::iterator i = clabelDefList_.find(id); if (i == clabelDefList_.end()) return; if (i->second.refCount == 1) { @@ -1248,11 +1264,23 @@ class LabelManager { #endif return !list.empty(); } + // detach all labels linked to LabelManager + void resetLabelPtrList() + { + for (LabelPtrList::iterator i = labelPtrList_.begin(), ie = labelPtrList_.end(); i != ie; ++i) { + (*i)->clear(); + } + labelPtrList_.clear(); + } public: LabelManager() { reset(); } + ~LabelManager() + { + resetLabelPtrList(); + } void reset() { base_ = 0; @@ -1262,6 +1290,7 @@ public: stateList_.push_back(SlabelState()); clabelDefList_.clear(); clabelUndefList_.clear(); + resetLabelPtrList(); } void enterLocal() { @@ -1294,10 +1323,11 @@ public: SlabelState& st = *label.c_str() == '.' ? stateList_.back() : stateList_.front(); define_inner(st.defList, st.undefList, label, base_->getSize()); } - void defineClabel(const Label& label) + void defineClabel(Label& label) { define_inner(clabelDefList_, clabelUndefList_, getId(label), base_->getSize()); label.mgr = this; + labelPtrList_.insert(&label); } void assign(Label& dst, const Label& src) { @@ -1305,6 +1335,7 @@ public: if (i == clabelDefList_.end()) throw Error(ERR_LABEL_ISNOT_SET_BY_L); define_inner(clabelDefList_, clabelUndefList_, dst.id, i->second.offset); dst.mgr = this; + labelPtrList_.insert(&dst); } bool getOffset(size_t *offset, std::string& label) const { @@ -1352,19 +1383,19 @@ inline Label::Label(const Label& rhs) { id = rhs.id; mgr = rhs.mgr; - if (mgr) mgr->incRefCount(id); + if (mgr) mgr->incRefCount(id, this); } inline Label& Label::operator=(const Label& rhs) { if (id) throw Error(ERR_LABEL_IS_ALREADY_SET_BY_L); id = rhs.id; mgr = rhs.mgr; - if (mgr) mgr->incRefCount(id); + if (mgr) mgr->incRefCount(id, this); return *this; } inline Label::~Label() { - if (id && mgr) mgr->decRefCount(id); + if (id && mgr) mgr->decRefCount(id, this); } inline const uint8* Label::getAddress() const { @@ -2168,7 +2199,7 @@ public: const Segment es, cs, ss, ds, fs, gs; #endif void L(const std::string& label) { labelMgr_.defineSlabel(label); } - void L(const Label& label) { labelMgr_.defineClabel(label); } + void L(Label& label) { labelMgr_.defineClabel(label); } Label L() { Label label; L(label); return label; } void inLocalLabel() { labelMgr_.enterLocal(); } void outLocalLabel() { labelMgr_.leaveLocal(); } @@ -2200,7 +2231,7 @@ public: // call(function pointer) #ifdef XBYAK_VARIADIC_TEMPLATE template<class Ret, class... Params> - void call(Ret(*func)(Params...)) { call(CastTo<const void*>(func)); } + void call(Ret(*func)(Params...)) { call(reinterpret_cast<const void*>(func)); } #endif void call(const void *addr) { opJmpAbs(addr, T_NEAR, 0, 0xE8); } diff --git a/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak_mnemonic.h b/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak_mnemonic.h index 92a31f9a1..766f2f6ec 100644 --- a/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak_mnemonic.h +++ b/vendor/github.com/dexon-foundation/mcl/src/xbyak/xbyak_mnemonic.h @@ -1,4 +1,4 @@ -const char *getVersionString() const { return "5.73"; } +const char *getVersionString() const { return "5.751"; } void adc(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x10, 2); } void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); } void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); } diff --git a/vendor/github.com/dexon-foundation/mcl/test/aggregate_sig_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/aggregate_sig_test.cpp new file mode 100644 index 000000000..c3a0e758d --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/aggregate_sig_test.cpp @@ -0,0 +1,74 @@ +//#define MCLBN_FP_UNIT_SIZE 8 +#include <cybozu/test.hpp> +#include <mcl/aggregate_sig.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/xorshift.hpp> + +using namespace mcl::aggs; + +CYBOZU_TEST_AUTO(init) +{ + AGGS::init(); +// AGGS::init(mcl::BN381_1); +// AGGS::init(mcl::BLS12_381); + SecretKey sec; + sec.init(); + PublicKey pub; + sec.getPublicKey(pub); + const std::string m = "abc"; + Signature sig; + sec.sign(sig, m); + CYBOZU_TEST_ASSERT(pub.verify(sig, m)); +} + +void aggregateTest(const std::vector<std::string>& msgVec) +{ + const size_t n = msgVec.size(); + std::vector<SecretKey> secVec(n); + std::vector<PublicKey> pubVec(n); + std::vector<Signature> sigVec(n); + Signature aggSig; + for (size_t i = 0; i < n; i++) { + secVec[i].init(); + secVec[i].getPublicKey(pubVec[i]); + secVec[i].sign(sigVec[i], msgVec[i]); + CYBOZU_TEST_ASSERT(pubVec[i].verify(sigVec[i], msgVec[i])); + } + aggSig.aggregate(sigVec); + CYBOZU_TEST_ASSERT(aggSig.verify(msgVec, pubVec)); + CYBOZU_BENCH_C("aggSig.verify", 10, aggSig.verify, msgVec, pubVec); +} + +CYBOZU_TEST_AUTO(aggregate) +{ +#if 0 + /* + Core i7-7700 CPU @ 3.60GHz + BN254 Fp382 Fp462 + security bit 100 115? 128 + # of sig 100 69 200 476 + 1000 693 2037 4731 + 10000 6969 20448 47000(Mclk) + */ + const size_t n = 1000; + const size_t msgSize = 16; + std::vector<std::string> msgVec(n); + cybozu::XorShift rg; + for (size_t i = 0; i < n; i++) { + std::string& msg = msgVec[i]; + msg.resize(msgSize); + for (size_t j = 0; j < msgSize; j++) { + msg[j] = (char)rg(); + } + } + aggregateTest(msgVec); +#else + const std::string msgArray[] = { "abc", "12345", "xyz", "pqr", "aggregate signature" }; + const size_t n = sizeof(msgArray) / sizeof(msgArray[0]); + std::vector<std::string> msgVec(n); + for (size_t i = 0; i < n; i++) { + msgVec[i] = msgArray[i]; + } + aggregateTest(msgVec); +#endif +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/array_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/array_test.cpp new file mode 100644 index 000000000..2168a28fa --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/array_test.cpp @@ -0,0 +1,104 @@ +#include <mcl/array.hpp> +#include <cybozu/test.hpp> + +template<class Array, size_t n> +void setArray(Array& a, const int (&tbl)[n]) +{ + CYBOZU_TEST_ASSERT(a.resize(n)); + for (size_t i = 0; i < n; i++) a[i] = tbl[i]; +} + +template<class Array, size_t an, size_t bn> +void swapTest(const int (&a)[an], const int (&b)[bn]) +{ + Array s, t; + setArray(s, a); + setArray(t, b); + s.swap(t); + CYBOZU_TEST_EQUAL(s.size(), bn); + CYBOZU_TEST_EQUAL(t.size(), an); + CYBOZU_TEST_EQUAL_ARRAY(s, b, s.size()); + CYBOZU_TEST_EQUAL_ARRAY(t, a, t.size()); +} + +CYBOZU_TEST_AUTO(resize) +{ + mcl::Array<int> a, b; + CYBOZU_TEST_EQUAL(a.size(), 0); + CYBOZU_TEST_EQUAL(b.size(), 0); + + const size_t n = 5; + bool ok = a.resize(n); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(n, a.size()); + for (size_t i = 0; i < n; i++) { + a[i] = i; + } + ok = b.copy(a); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), n); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), n); + + const size_t small = n - 1; + ok = b.resize(small); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), small); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), small); + const size_t large = n * 2; + ok = b.resize(large); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), large); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), small); + + const int aTbl[] = { 3, 4 }; + const int bTbl[] = { 7, 6, 5, 3 }; + swapTest<mcl::Array<int> >(aTbl, bTbl); + swapTest<mcl::Array<int> >(bTbl, aTbl); +} + +CYBOZU_TEST_AUTO(FixedArray) +{ + const size_t n = 5; + mcl::FixedArray<int, n> a, b; + CYBOZU_TEST_EQUAL(a.size(), 0); + CYBOZU_TEST_EQUAL(b.size(), 0); + + bool ok = a.resize(n); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(n, a.size()); + for (size_t i = 0; i < n; i++) { + a[i] = i; + } + ok = b.copy(a); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), n); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), n); + + const size_t small = n - 1; + ok = b.resize(small); + CYBOZU_TEST_ASSERT(ok); + CYBOZU_TEST_EQUAL(b.size(), small); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), small); + const size_t large = n + 1; + ok = b.resize(large); + CYBOZU_TEST_ASSERT(!ok); + + const int aTbl[] = { 3, 4 }; + const int bTbl[] = { 7, 6, 5, 3 }; + swapTest<mcl::FixedArray<int, n> >(aTbl, bTbl); + swapTest<mcl::FixedArray<int, n> >(bTbl, aTbl); +} + +#ifndef CYBOZU_DONT_USE_EXCEPTION +CYBOZU_TEST_AUTO(assign) +{ + const int aTbl[] = { 3, 4, 2 }; + const int bTbl[] = { 3, 4, 2, 1, 5 }; + mcl::Array<int> a, b; + setArray(a, aTbl); + setArray(b, bTbl); + a = b; + CYBOZU_TEST_EQUAL(a.size(), b.size()); + CYBOZU_TEST_EQUAL_ARRAY(a.data(), b.data(), a.size()); +} +#endif diff --git a/vendor/github.com/dexon-foundation/mcl/test/base_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/base_test.cpp new file mode 100644 index 000000000..2733d17ca --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/base_test.cpp @@ -0,0 +1,392 @@ +// not compiled +#include <map> +#include <mcl/op.hpp> +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/xorshift.hpp> +#include <cybozu/bit_operation.hpp> +#include <mcl/conversion.hpp> +#include <mcl/fp.hpp> + +#include "../src/fp_generator.hpp" +#if (CYBOZU_HOST == CYBOZU_HOST_INTEL) && (MCL_SIZEOF_UNIT == 8) + #define USE_XBYAK + static mcl::FpGenerator fg; +#endif +#define PUT(x) std::cout << #x "=" << (x) << std::endl + +const size_t MAX_N = 32; +typedef mcl::fp::Unit Unit; + +size_t getUnitSize(size_t bitSize) +{ + return (bitSize + sizeof(Unit) * 8 - 1) / (sizeof(Unit) * 8); +} + +void setMpz(mpz_class& mx, const Unit *x, size_t n) +{ + mcl::gmp::setArray(mx, x, n); +} +void getMpz(Unit *x, size_t n, const mpz_class& mx) +{ + mcl::fp::toArray(x, n, mx.get_mpz_t()); +} + +struct Montgomery { + mpz_class p_; + mpz_class R_; // (1 << (n_ * 64)) % p + mpz_class RR_; // (R * R) % p + Unit r_; // p * r = -1 mod M = 1 << 64 + size_t n_; + Montgomery() {} + explicit Montgomery(const mpz_class& p) + { + p_ = p; + r_ = mcl::montgomery::getCoff(mcl::gmp::getUnit(p, 0)); + n_ = mcl::gmp::getUnitSize(p); + R_ = 1; + R_ = (R_ << (n_ * 64)) % p_; + RR_ = (R_ * R_) % p_; + } + + void toMont(mpz_class& x) const { mul(x, x, RR_); } + void fromMont(mpz_class& x) const { mul(x, x, 1); } + + void mont(Unit *z, const Unit *x, const Unit *y) const + { + mpz_class mx, my; + setMpz(mx, x, n_); + setMpz(my, y, n_); + mul(mx, mx, my); + getMpz(z, n_, mx); + } + void mul(mpz_class& z, const mpz_class& x, const mpz_class& y) const + { +#if 1 + const size_t ySize = mcl::gmp::getUnitSize(y); + mpz_class c = y == 0 ? mpz_class(0) : x * mcl::gmp::getUnit(y, 0); + Unit q = c == 0 ? 0 : mcl::gmp::getUnit(c, 0) * r_; + c += p_ * q; + c >>= sizeof(Unit) * 8; + for (size_t i = 1; i < n_; i++) { + if (i < ySize) { + c += x * mcl::gmp::getUnit(y, i); + } + Unit q = c == 0 ? 0 : mcl::gmp::getUnit(c, 0) * r_; + c += p_ * q; + c >>= sizeof(Unit) * 8; + } + if (c >= p_) { + c -= p_; + } + z = c; +#else + z = x * y; + const size_t zSize = mcl::gmp::getUnitSize(z); + for (size_t i = 0; i < n_; i++) { + if (i < zSize) { + Unit q = mcl::gmp::getUnit(z, 0) * r_; + z += p_ * (mp_limb_t)q; + } + z >>= sizeof(Unit) * 8; + } + if (z >= p_) { + z -= p_; + } +#endif + } +}; + +void put(const char *msg, const Unit *x, size_t n) +{ + printf("%s ", msg); + for (size_t i = 0; i < n; i++) printf("%016llx ", (long long)x[n - 1 - i]); + printf("\n"); +} +void verifyEqual(const Unit *x, const Unit *y, size_t n, const char *file, int line) +{ + bool ok = mcl::fp::isEqualArray(x, y, n); + CYBOZU_TEST_ASSERT(ok); + if (ok) return; + printf("%s:%d\n", file, line); + put("L", x, n); + put("R", y, n); + exit(1); +} +#define VERIFY_EQUAL(x, y, n) verifyEqual(x, y, n, __FILE__, __LINE__) + +void addC(Unit *z, const Unit *x, const Unit *y, const Unit *p, size_t n) +{ + mpz_class mx, my, mp; + setMpz(mx, x, n); + setMpz(my, y, n); + setMpz(mp, p, n); + mx += my; + if (mx >= mp) mx -= mp; + getMpz(z, n, mx); +} +void subC(Unit *z, const Unit *x, const Unit *y, const Unit *p, size_t n) +{ + mpz_class mx, my, mp; + setMpz(mx, x, n); + setMpz(my, y, n); + setMpz(mp, p, n); + mx -= my; + if (mx < 0) mx += mp; + getMpz(z, n, mx); +} +static inline void set_zero(mpz_t& z, Unit *p, size_t n) +{ + z->_mp_alloc = (int)n; + z->_mp_size = 0; + z->_mp_d = (mp_limb_t*)p; +} +static inline void set_mpz_t(mpz_t& z, const Unit* p, int n) +{ + z->_mp_alloc = n; + int i = n; + while (i > 0 && p[i - 1] == 0) { + i--; + } + z->_mp_size = i; + z->_mp_d = (mp_limb_t*)p; +} + +// z[2n] <- x[n] * y[n] +void mulPreC(Unit *z, const Unit *x, const Unit *y, size_t n) +{ +#if 1 + mpz_t mx, my, mz; + set_zero(mz, z, n * 2); + set_mpz_t(mx, x, n); + set_mpz_t(my, y, n); + mpz_mul(mz, mx, my); + mcl::fp::toArray(z, n * 2, mz); +#else + mpz_class mx, my; + setMpz(mx, x, n); + setMpz(my, y, n); + mx *= my; + getMpz(z, n * 2, mx); +#endif +} + +void modC(Unit *y, const Unit *x, const Unit *p, size_t n) +{ + mpz_t mx, my, mp; + set_mpz_t(mx, x, n * 2); + set_mpz_t(my, y, n); + set_mpz_t(mp, p, n); + mpz_mod(my, mx, mp); + mcl::fp::clearArray(y, my->_mp_size, n); +} + +void mul(Unit *z, const Unit *x, const Unit *y, const Unit *p, size_t n) +{ + Unit ret[MAX_N * 2]; + mpz_t mx, my, mz, mp; + set_zero(mz, ret, MAX_N * 2); + set_mpz_t(mx, x, n); + set_mpz_t(my, y, n); + set_mpz_t(mp, p, n); + mpz_mul(mz, mx, my); + mpz_mod(mz, mz, mp); + mcl::fp::toArray(z, n, mz); +} + +typedef mcl::fp::void3op void3op; +typedef mcl::fp::void4op void4op; +typedef mcl::fp::void4Iop void4Iop; + +const struct FuncOp { + size_t bitSize; + void4op addS; + void4op addL; + void4op subS; + void4op subL; + void3op mulPre; + void4Iop mont; +} gFuncOpTbl[] = { + { 128, mcl_fp_add128S, mcl_fp_add128L, mcl_fp_sub128S, mcl_fp_sub128L, mcl_fp_mul128pre, mcl_fp_mont128 }, + { 192, mcl_fp_add192S, mcl_fp_add192L, mcl_fp_sub192S, mcl_fp_sub192L, mcl_fp_mul192pre, mcl_fp_mont192 }, + { 256, mcl_fp_add256S, mcl_fp_add256L, mcl_fp_sub256S, mcl_fp_sub256L, mcl_fp_mul256pre, mcl_fp_mont256 }, + { 320, mcl_fp_add320S, mcl_fp_add320L, mcl_fp_sub320S, mcl_fp_sub320L, mcl_fp_mul320pre, mcl_fp_mont320 }, + { 384, mcl_fp_add384S, mcl_fp_add384L, mcl_fp_sub384S, mcl_fp_sub384L, mcl_fp_mul384pre, mcl_fp_mont384 }, + { 448, mcl_fp_add448S, mcl_fp_add448L, mcl_fp_sub448S, mcl_fp_sub448L, mcl_fp_mul448pre, mcl_fp_mont448 }, + { 512, mcl_fp_add512S, mcl_fp_add512L, mcl_fp_sub512S, mcl_fp_sub512L, mcl_fp_mul512pre, mcl_fp_mont512 }, +#if MCL_SIZEOF_UNIT == 4 + { 160, mcl_fp_add160S, mcl_fp_add160L, mcl_fp_sub160S, mcl_fp_sub160L, mcl_fp_mul160pre, mcl_fp_mont160 }, + { 224, mcl_fp_add224S, mcl_fp_add224L, mcl_fp_sub224S, mcl_fp_sub224L, mcl_fp_mul224pre, mcl_fp_mont224 }, + { 288, mcl_fp_add288S, mcl_fp_add288L, mcl_fp_sub288S, mcl_fp_sub288L, mcl_fp_mul288pre, mcl_fp_mont288 }, + { 352, mcl_fp_add352S, mcl_fp_add352L, mcl_fp_sub352S, mcl_fp_sub352L, mcl_fp_mul352pre, mcl_fp_mont352 }, + { 416, mcl_fp_add416S, mcl_fp_add416L, mcl_fp_sub416S, mcl_fp_sub416L, mcl_fp_mul416pre, mcl_fp_mont416 }, + { 480, mcl_fp_add480S, mcl_fp_add480L, mcl_fp_sub480S, mcl_fp_sub480L, mcl_fp_mul480pre, mcl_fp_mont480 }, + { 544, mcl_fp_add544S, mcl_fp_add544L, mcl_fp_sub544S, mcl_fp_sub544L, mcl_fp_mul544pre, mcl_fp_mont544 }, +#else + { 576, mcl_fp_add576S, mcl_fp_add576L, mcl_fp_sub576S, mcl_fp_sub576L, mcl_fp_mul576pre, mcl_fp_mont576 }, +#endif +}; + +FuncOp getFuncOp(size_t bitSize) +{ + typedef std::map<size_t, FuncOp> Map; + static Map map; + static bool init = false; + if (!init) { + init = true; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(gFuncOpTbl); i++) { + map[gFuncOpTbl[i].bitSize] = gFuncOpTbl[i]; + } + } + for (Map::const_iterator i = map.begin(), ie = map.end(); i != ie; ++i) { + if (bitSize <= i->second.bitSize) { + return i->second; + } + } + printf("ERR bitSize=%d\n", (int)bitSize); + exit(1); +} + +void test(const Unit *p, size_t bitSize) +{ + printf("bitSize %d\n", (int)bitSize); + const size_t n = getUnitSize(bitSize); +#ifdef NDEBUG + bool doBench = true; +#else + bool doBench = false; +#endif + const FuncOp funcOp = getFuncOp(bitSize); + const void4op addS = funcOp.addS; + const void4op addL = funcOp.addL; + const void4op subS = funcOp.subS; + const void4op subL = funcOp.subL; + const void3op mulPre = funcOp.mulPre; + const void4Iop mont = funcOp.mont; + + mcl::fp::Unit x[MAX_N], y[MAX_N]; + mcl::fp::Unit z[MAX_N], w[MAX_N]; + mcl::fp::Unit z2[MAX_N * 2]; + mcl::fp::Unit w2[MAX_N * 2]; + cybozu::XorShift rg; + mcl::fp::getRandVal(x, rg, p, bitSize); + mcl::fp::getRandVal(y, rg, p, bitSize); + const size_t C = 10; + + addC(z, x, y, p, n); + addS(w, x, y, p); + VERIFY_EQUAL(z, w, n); + for (size_t i = 0; i < C; i++) { + addC(z, y, z, p, n); + addS(w, y, w, p); + VERIFY_EQUAL(z, w, n); + addC(z, y, z, p, n); + addL(w, y, w, p); + VERIFY_EQUAL(z, w, n); + subC(z, x, z, p, n); + subS(w, x, w, p); + VERIFY_EQUAL(z, w, n); + subC(z, x, z, p, n); + subL(w, x, w, p); + VERIFY_EQUAL(z, w, n); + mulPreC(z2, x, z, n); + mulPre(w2, x, z); + VERIFY_EQUAL(z2, w2, n * 2); + } + { + mpz_class mp; + setMpz(mp, p, n); + Montgomery m(mp); +#ifdef USE_XBYAK + if (bitSize > 128) fg.init(p, n); +#endif + /* + real mont + 0 0 + 1 R^-1 + R 1 + -1 -R^-1 + -R -1 + */ + mpz_class t = 1; + const mpz_class R = (t << (n * 64)) % mp; + const mpz_class tbl[] = { + 0, 1, R, mp - 1, mp - R + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const mpz_class& mx = tbl[i]; + for (size_t j = i; j < CYBOZU_NUM_OF_ARRAY(tbl); j++) { + const mpz_class& my = tbl[j]; + getMpz(x, n, mx); + getMpz(y, n, my); + m.mont(z, x, y); + mont(w, x, y, p, m.r_); + VERIFY_EQUAL(z, w, n); +#ifdef USE_XBYAK + if (bitSize > 128) { + fg.mul_(w, x, y); + VERIFY_EQUAL(z, w, n); + } +#endif + } + } + if (doBench) { +// CYBOZU_BENCH("montC", m.mont, x, y, x); + CYBOZU_BENCH("montA ", mont, x, y, x, p, m.r_); + } + } + if (doBench) { +// CYBOZU_BENCH("addS", addS, x, y, x, p); // slow +// CYBOZU_BENCH("subS", subS, x, y, x, p); +// CYBOZU_BENCH("addL", addL, x, y, x, p); +// CYBOZU_BENCH("subL", subL, x, y, x, p); + CYBOZU_BENCH("mulPreA", mulPre, w2, y, x); + CYBOZU_BENCH("mulPreC", mulPreC, w2, y, x, n); + CYBOZU_BENCH("modC ", modC, x, w2, p, n); + } +#ifdef USE_XBYAK + if (bitSize <= 128) return; + if (doBench) { + fg.init(p, n); + CYBOZU_BENCH("addA ", fg.add_, x, y, x); + CYBOZU_BENCH("subA ", fg.sub_, x, y, x); +// CYBOZU_BENCH("mulA", fg.mul_, x, y, x); + } +#endif + printf("mont test %d\n", (int)bitSize); +} + +CYBOZU_TEST_AUTO(all) +{ + const struct { + size_t n; + const uint64_t p[9]; + } tbl[] = { +// { 2, { 0xf000000000000001, 1, } }, + { 2, { 0x000000000000001d, 0x8000000000000000, } }, + { 3, { 0x000000000000012b, 0x0000000000000000, 0x0000000080000000, } }, +// { 3, { 0x0f69466a74defd8d, 0xfffffffe26f2fc17, 0x07ffffffffffffff, } }, +// { 3, { 0x7900342423332197, 0x1234567890123456, 0x1480948109481904, } }, + { 3, { 0x0f69466a74defd8d, 0xfffffffe26f2fc17, 0xffffffffffffffff, } }, +// { 4, { 0x7900342423332197, 0x4242342420123456, 0x1234567892342342, 0x1480948109481904, } }, +// { 4, { 0x0f69466a74defd8d, 0xfffffffe26f2fc17, 0x17ffffffffffffff, 0x1513423423423415, } }, + { 4, { 0xa700000000000013, 0x6121000000000013, 0xba344d8000000008, 0x2523648240000001, } }, +// { 5, { 0x0000000000000009, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8000000000000000, } }, + { 5, { 0xfffffffffffffc97, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, } }, +// { 6, { 0x4720422423332197, 0x0034230847204720, 0x3456789012345679, 0x4820984290482212, 0x9482094820948209, 0x0194810841094810, } }, +// { 6, { 0x7204224233321972, 0x0342308472047204, 0x4567890123456790, 0x0948204204243123, 0x2098420984209482, 0x2093482094810948, } }, + { 6, { 0x00000000ffffffff, 0xffffffff00000000, 0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, } }, +// { 7, { 0x0000000000000063, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x8000000000000000, } }, + { 7, { 0x000000000fffcff1, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, } }, + { 8, { 0xffffffffffffd0c9, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, } }, + { 9, { 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x00000000000001ff, } }, +// { 9, { 0x4720422423332197, 0x0034230847204720, 0x3456789012345679, 0x2498540975555312, 0x9482904924029424, 0x0948209842098402, 0x1098410948109482, 0x0820958209582094, 0x0000000000000029, } }, +// { 9, { 0x0f69466a74defd8d, 0xfffffffe26f2fc17, 0x7fffffffffffffff, 0x8572938572398583, 0x5732057823857293, 0x9820948205872380, 0x3409238420492034, 0x9483842098340298, 0x0000000000000003, } }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const size_t n = tbl[i].n; + const size_t bitSize = (n - 1) * 64 + cybozu::bsr<uint64_t>(tbl[i].p[n - 1]) + 1; + test((const Unit*)tbl[i].p, bitSize); + } +} + diff --git a/vendor/github.com/dexon-foundation/mcl/test/bench.hpp b/vendor/github.com/dexon-foundation/mcl/test/bench.hpp new file mode 100644 index 000000000..cc1639e6e --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bench.hpp @@ -0,0 +1,192 @@ +#include <mcl/lagrange.hpp> + +void benchAddDblG1() +{ + puts("benchAddDblG1"); + const int C = 100000; + G1 P1, P2, P3; + hashAndMapToG1(P1, "a"); + hashAndMapToG1(P2, "b"); + P1 += P2; + P2 += P1; + printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne()); + CYBOZU_BENCH_C("G1::add(1)", C, G1::add, P3, P1, P2); + P1.normalize(); + printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne()); + CYBOZU_BENCH_C("G1::add(2)", C, G1::add, P3, P1, P2); + CYBOZU_BENCH_C("G1::add(3)", C, G1::add, P3, P2, P1); + P2.normalize(); + printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne()); + CYBOZU_BENCH_C("G1::add(4)", C, G1::add, P3, P1, P2); + P1 = P3; + printf("z.isOne()=%d\n", P1.z.isOne()); + CYBOZU_BENCH_C("G1::dbl(1)", C, G1::dbl, P3, P1); + P1.normalize(); + printf("z.isOne()=%d\n", P1.z.isOne()); + CYBOZU_BENCH_C("G1::dbl(2)", C, G1::dbl, P3, P1); +} + +void benchAddDblG2() +{ + puts("benchAddDblG2"); + const int C = 100000; + G2 P1, P2, P3; + hashAndMapToG2(P1, "a"); + hashAndMapToG2(P2, "b"); + P1 += P2; + P2 += P1; + printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne()); + CYBOZU_BENCH_C("G2::add(1)", C, G2::add, P3, P1, P2); + P1.normalize(); + printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne()); + CYBOZU_BENCH_C("G2::add(2)", C, G2::add, P3, P1, P2); + CYBOZU_BENCH_C("G2::add(3)", C, G2::add, P3, P2, P1); + P2.normalize(); + printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne()); + CYBOZU_BENCH_C("G2::add(4)", C, G2::add, P3, P1, P2); + P1 = P3; + printf("z.isOne()=%d\n", P1.z.isOne()); + CYBOZU_BENCH_C("G2::dbl(1)", C, G2::dbl, P3, P1); + P1.normalize(); + printf("z.isOne()=%d\n", P1.z.isOne()); + CYBOZU_BENCH_C("G2::dbl(2)", C, G2::dbl, P3, P1); +} + + +void testBench(const G1& P, const G2& Q) +{ + G1 Pa; + G2 Qa; + Fp12 e1, e2; + pairing(e1, P, Q); + Fp12::pow(e2, e1, 12345); + Fp x, y; + x.setHashOf("abc"); + y.setHashOf("xyz"); + const int C = 1000; + const int C3 = 100000; +#if 1 + const int C2 = 3000; + mpz_class a = x.getMpz(); + CYBOZU_BENCH_C("G1::mulCT ", C, G1::mulCT, Pa, P, a); + CYBOZU_BENCH_C("G1::mul ", C, G1::mul, Pa, Pa, a); + CYBOZU_BENCH_C("G1::add ", C, G1::add, Pa, Pa, P); + CYBOZU_BENCH_C("G1::dbl ", C, G1::dbl, Pa, Pa); + CYBOZU_BENCH_C("G2::mulCT ", C, G2::mulCT, Qa, Q, a); + CYBOZU_BENCH_C("G2::mul ", C, G2::mul, Qa, Qa, a); + CYBOZU_BENCH_C("G2::add ", C, G2::add, Qa, Qa, Q); + CYBOZU_BENCH_C("G2::dbl ", C, G2::dbl, Qa, Qa); + CYBOZU_BENCH_C("GT::pow ", C, GT::pow, e1, e1, a); +// CYBOZU_BENCH_C("GT::powGLV ", C, BN::param.glv2.pow, e1, e1, a); + G1 PP; + G2 QQ; + std::string s; + s = P.getStr(); + CYBOZU_BENCH_C("G1::setStr chk", C, PP.setStr, s); + verifyOrderG1(false); + CYBOZU_BENCH_C("G1::setStr ", C, PP.setStr, s); + verifyOrderG1(true); + s = Q.getStr(); + CYBOZU_BENCH_C("G2::setStr chk", C, QQ.setStr, s); + verifyOrderG2(false); + CYBOZU_BENCH_C("G2::setStr ", C, QQ.setStr, s); + verifyOrderG2(true); + CYBOZU_BENCH_C("hashAndMapToG1", C, hashAndMapToG1, PP, "abc", 3); + CYBOZU_BENCH_C("hashAndMapToG2", C, hashAndMapToG2, QQ, "abc", 3); +#endif + CYBOZU_BENCH_C("Fp::add ", C3, Fp::add, x, x, y); + CYBOZU_BENCH_C("Fp::sub ", C3, Fp::sub, x, x, y); + CYBOZU_BENCH_C("Fp::neg ", C3, Fp::neg, x, x); + CYBOZU_BENCH_C("Fp::mul ", C3, Fp::mul, x, x, y); + CYBOZU_BENCH_C("Fp::sqr ", C3, Fp::sqr, x, x); + CYBOZU_BENCH_C("Fp::inv ", C3, Fp::inv, x, x); + Fp2 xx, yy; + xx.a = x; + xx.b = 3; + yy.a = y; + yy.b = -5; + FpDbl d0, d1; + x = 9; + y = 3; +#if 1 + CYBOZU_BENCH_C("Fp2::add ", C3, Fp2::add, xx, xx, yy); + CYBOZU_BENCH_C("Fp2::sub ", C3, Fp2::sub, xx, xx, yy); + CYBOZU_BENCH_C("Fp2::neg ", C3, Fp2::neg, xx, xx); + CYBOZU_BENCH_C("Fp2::mul ", C3, Fp2::mul, xx, xx, yy); + CYBOZU_BENCH_C("Fp2::mul_xi ", C3, Fp2::mul_xi, xx, xx); + CYBOZU_BENCH_C("Fp2::sqr ", C3, Fp2::sqr, xx, xx); + CYBOZU_BENCH_C("Fp2::inv ", C3, Fp2::inv, xx, xx); + CYBOZU_BENCH_C("FpDbl::addPre ", C3, FpDbl::addPre, d1, d1, d0); + CYBOZU_BENCH_C("FpDbl::subPre ", C3, FpDbl::subPre, d1, d1, d0); + CYBOZU_BENCH_C("FpDbl::add ", C3, FpDbl::add, d1, d1, d0); + CYBOZU_BENCH_C("FpDbl::sub ", C3, FpDbl::sub, d1, d1, d0); + CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y); + CYBOZU_BENCH_C("FpDbl::sqrPre ", C3, FpDbl::sqrPre, d1, x); + CYBOZU_BENCH_C("FpDbl::mod ", C3, FpDbl::mod, x, d0); + Fp2Dbl D; + CYBOZU_BENCH_C("Fp2Dbl::mulPre ", C3, Fp2Dbl::mulPre, D, xx, yy); + CYBOZU_BENCH_C("Fp2Dbl::sqrPre ", C3, Fp2Dbl::sqrPre, D, xx); + + CYBOZU_BENCH_C("GT::add ", C2, GT::add, e1, e1, e2); + CYBOZU_BENCH_C("GT::mul ", C2, GT::mul, e1, e1, e2); + CYBOZU_BENCH_C("GT::sqr ", C2, GT::sqr, e1, e1); + CYBOZU_BENCH_C("GT::inv ", C2, GT::inv, e1, e1); +#endif + CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y); + CYBOZU_BENCH_C("pairing ", 3000, pairing, e1, P, Q); + CYBOZU_BENCH_C("millerLoop ", 3000, millerLoop, e1, P, Q); + CYBOZU_BENCH_C("finalExp ", 3000, finalExp, e1, e1); +//exit(1); + std::vector<Fp6> Qcoeff; + CYBOZU_BENCH_C("precomputeG2 ", C, precomputeG2, Qcoeff, Q); + precomputeG2(Qcoeff, Q); + CYBOZU_BENCH_C("precomputedML ", C, precomputedMillerLoop, e2, P, Qcoeff); +} + +inline void SquareRootPrecomputeTest(const mpz_class& p) +{ + mcl::SquareRoot sq1, sq2; + bool b; + sq1.set(&b, p, true); + CYBOZU_TEST_ASSERT(b); + CYBOZU_TEST_ASSERT(sq1.isPrecomputed()); + sq2.set(&b, p, false); + CYBOZU_TEST_ASSERT(sq1 == sq2); + if (sq1 != sq2) { + puts("dump"); + puts("sq1"); + sq1.dump(); + puts("sq2"); + sq2.dump(); + puts("---"); + } +} + +void testSquareRoot() +{ + if (BN::param.cp == mcl::BN254 || BN::param.cp == mcl::BLS12_381) { + SquareRootPrecomputeTest(BN::param.p); + SquareRootPrecomputeTest(BN::param.r); + } +} + +void testLagrange() +{ + puts("testLagrange"); + const int k = 7; + Fr c[k], x[k], y[k]; + for (size_t i = 0; i < k; i++) { + c[i].setByCSPRNG(); + x[i].setByCSPRNG(); + } + for (size_t i = 0; i < k; i++) { + mcl::evaluatePolynomial(y[i], c, k, x[i]); + } + Fr s; + mcl::LagrangeInterpolation(s, x, y, k); + CYBOZU_TEST_EQUAL(s, c[0]); + mcl::LagrangeInterpolation(s, x, y, 1); + CYBOZU_TEST_EQUAL(s, y[0]); + mcl::evaluatePolynomial(y[0], c, 1, x[0]); + CYBOZU_TEST_EQUAL(y[0], c[0]); +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/bls12_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bls12_test.cpp new file mode 100644 index 000000000..7011516bd --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bls12_test.cpp @@ -0,0 +1,720 @@ +#define PUT(x) std::cout << #x "=" << x << std::endl; +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/benchmark.hpp> +cybozu::CpuClock clk; +#include <cybozu/test.hpp> +#include <mcl/bls12_381.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> + +#if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST) + #define MCL_AVOID_EXCEPTION_TEST +#endif + +using namespace mcl::bls12; + +mcl::fp::Mode g_mode; + +const struct TestSet { + mcl::CurveParam cp; + const char *name; + const char *p; + const char *r; + struct G2 { + const char *aa; + const char *ab; + const char *ba; + const char *bb; + } g2; + struct G1 { + const char *a; + const char *b; + } g1; + const char *e; +} g_testSetTbl[] = { + { + mcl::BLS12_381, + "BLS12_381", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", + "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", + { + "0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + "0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e", + "0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801", + "0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be", + }, + { + "0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", + "0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", + }, + "0x1250EBD871FC0A92A7B2D83168D0D727272D441BEFA15C503DD8E90CE98DB3E7B6D194F60839C508A84305AACA1789B6 " + "0x089A1C5B46E5110B86750EC6A532348868A84045483C92B7AF5AF689452EAFABF1A8943E50439F1D59882A98EAA0170F " + "0x1368BB445C7C2D209703F239689CE34C0378A68E72A6B3B216DA0E22A5031B54DDFF57309396B38C881C4C849EC23E87 " + "0x193502B86EDB8857C273FA075A50512937E0794E1E65A7617C90D8BD66065B1FFFE51D7A579973B1315021EC3C19934F " + "0x01B2F522473D171391125BA84DC4007CFBF2F8DA752F7C74185203FCCA589AC719C34DFFBBAAD8431DAD1C1FB597AAA5 " + "0x018107154F25A764BD3C79937A45B84546DA634B8F6BE14A8061E55CCEBA478B23F7DACAA35C8CA78BEAE9624045B4B6 " + "0x19F26337D205FB469CD6BD15C3D5A04DC88784FBB3D0B2DBDEA54D43B2B73F2CBB12D58386A8703E0F948226E47EE89D " + "0x06FBA23EB7C5AF0D9F80940CA771B6FFD5857BAAF222EB95A7D2809D61BFE02E1BFD1B68FF02F0B8102AE1C2D5D5AB1A " + "0x11B8B424CD48BF38FCEF68083B0B0EC5C81A93B330EE1A677D0D15FF7B984E8978EF48881E32FAC91B93B47333E2BA57 " + "0x03350F55A7AEFCD3C31B4FCB6CE5771CC6A0E9786AB5973320C806AD360829107BA810C5A09FFDD9BE2291A0C25A99A2 " + "0x04C581234D086A9902249B64728FFD21A189E87935A954051C7CDBA7B3872629A4FAFC05066245CB9108F0242D0FE3EF " + "0x0F41E58663BF08CF068672CBD01A7EC73BACA4D72CA93544DEFF686BFD6DF543D48EAA24AFE47E1EFDE449383B676631 " + }, +}; + +CYBOZU_TEST_AUTO(size) +{ + CYBOZU_TEST_EQUAL(sizeof(Fp), 48u); + CYBOZU_TEST_EQUAL(sizeof(Fr), 32u); + CYBOZU_TEST_EQUAL(sizeof(Fp2), sizeof(Fp) * 2); + CYBOZU_TEST_EQUAL(sizeof(Fp6), sizeof(Fp) * 6); + CYBOZU_TEST_EQUAL(sizeof(Fp12), sizeof(Fp) * 12); + CYBOZU_TEST_EQUAL(sizeof(G1), sizeof(Fp) * 3); + CYBOZU_TEST_EQUAL(sizeof(G2), sizeof(Fp2) * 3); +} + +void testParam(const TestSet& ts) +{ + CYBOZU_TEST_EQUAL(BN::param.r, mpz_class(ts.r)); + CYBOZU_TEST_EQUAL(BN::param.p, mpz_class(ts.p)); +} + +void finalExpC(Fp12& y, const Fp12& x) +{ + const mpz_class& r = BN::param.r; + const mpz_class& p = BN::param.p; + mpz_class p2 = p * p; + mpz_class p4 = p2 * p2; +#if 1 + Fp12::pow(y, x, p2 + 1); + Fp12::pow(y, y, p4 * p2 - 1); + Fp12::pow(y, y, (p4 - p2 + 1) / r * 3); +#else + Fp12::pow(y, x, (p4 * p4 * p4 - 1) / r * 3); +#endif +} + +void pairingC(Fp12& e, const G1& P, const G2& Q) +{ + millerLoop(e, P, Q); + finalExp(e, e); +} +void testIoAll(const G1& P, const G2& Q) +{ + const int FpTbl[] = { 0, 2, 2|mcl::IoPrefix, 10, 16, 16|mcl::IoPrefix, mcl::IoArray, mcl::IoArrayRaw }; + const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(FpTbl); i++) { + for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(EcTbl); j++) { + G1 P2 = P, P3; + G2 Q2 = Q, Q3; + int ioMode = FpTbl[i] | EcTbl[j]; + std::string s = P2.getStr(ioMode); + P3.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(P2, P3); + s = Q2.getStr(ioMode); + Q3.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(Q2, Q3); + s = P.x.getStr(ioMode); + Fp Px; + Px.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(P.x, Px); + s = Q.x.getStr(ioMode); + Fp2 Qx; + Qx.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(Q.x, Qx); + } + } +} + +void testIo(const G1& P, const G2& Q) +{ + testIoAll(P, Q); + G1 Z1; + G2 Z2; + Z1.clear(); + Z2.clear(); + testIoAll(Z1, Z2); +} + +void testSetStr(const G2& Q0) +{ + G2::setCompressedExpression(); + G2 Q; + Q.clear(); + for (int i = 0; i < 10; i++) { + G2 R; + R.setStr(Q.getStr()); + CYBOZU_TEST_EQUAL(Q, R); + G2::add(Q, Q, Q0); + } +} + +void testMapToG1() +{ + G1 g; + for (int i = 1; i < 10; i++) { + mapToG1(g, i); + CYBOZU_TEST_ASSERT(!g.isZero()); + G1 gr; + G1::mul(gr, g, BN::param.r); + CYBOZU_TEST_ASSERT(gr.isZero()); + } +} + +void testMapToG2() +{ + G2 g; + for (int i = 1; i < 10; i++) { + mapToG2(g, i); + CYBOZU_TEST_ASSERT(!g.isZero()); + G2 gr; + G2::mul(gr, g, BN::param.r); + CYBOZU_TEST_ASSERT(gr.isZero()); + } + Fp x; + x.setHashOf("abc"); + mapToG2(g, Fp2(x, 0)); + CYBOZU_TEST_ASSERT(g.isValid()); +} + +void testPrecomputed(const G1& P, const G2& Q) +{ + Fp12 e1, e2; + pairing(e1, P, Q); + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e2, P, Qcoeff); + finalExp(e2, e2); + CYBOZU_TEST_EQUAL(e1, e2); +} + +#if 0 +void testFp12pow(const G1& P, const G2& Q) +{ + Fp12 e, e1, e2; + pairing(e, P, Q); + cybozu::XorShift rg; + for (int i = -10; i < 10; i++) { + mpz_class xm = i; + Fp12::pow(e1, e, xm); + Fp12::powGeneric(e2, e, xm); + CYBOZU_TEST_EQUAL(e1, e2); + } + for (int i = 0; i < 10; i++) { + Fr x; + x.setRand(rg); + mpz_class xm = x.getMpz(); + Fp12::pow(e1, e, xm); + param.glv2.pow(e2, e, xm); + CYBOZU_TEST_EQUAL(e1, e2); + } +} +#endif + +void testMillerLoop2(const G1& P1, const G2& Q1) +{ + Fp12 e1, e2, e3; + mpz_class c1("12342342423442"); + mpz_class c2("329428049820348209482"); + G2 Q2; + G1 P2; + G2::mul(Q2, Q1, c1); + G1::mul(P2, P1, c2); + pairing(e1, P1, Q1); + pairing(e2, P2, Q2); + e1 *= e2; + + std::vector<Fp6> Q1coeff, Q2coeff; + precomputeG2(Q1coeff, Q1); + precomputeG2(Q2coeff, Q2); + precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); + precomputedMillerLoop2mixed(e3, P1, Q1, P2, Q2coeff); + CYBOZU_TEST_EQUAL(e2, e3); + finalExp(e2, e2); + CYBOZU_TEST_EQUAL(e1, e2); + + // special value + G2 Z; + Z.clear(); + Q2 += Q2; + precomputeG2(Q1coeff, Z); + precomputeG2(Q2coeff, Q2); + precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); + precomputedMillerLoop2mixed(e3, P1, Z, P2, Q2coeff); + finalExp(e2, e2); + finalExp(e3, e3); + CYBOZU_TEST_EQUAL(e2, e3); +} + +void testPairing(const G1& P, const G2& Q, const char *eStr) +{ + Fp12 e1; + pairing(e1, P, Q); + Fp12 e2; + { + std::stringstream ss(eStr); + ss >> e2; + } + CYBOZU_TEST_EQUAL(e1, e2); + Fp12 e = e1, ea; + G1 Pa; + G2 Qa; +#if defined(__EMSCRIPTEN__) || MCL_SIZEOF_UNIT == 4 + const int count = 100; +#else + const int count = 1000; +#endif + mpz_class a; + cybozu::XorShift rg; + for (int i = 0; i < count; i++) { + Fr r; + r.setRand(rg); + a = r.getMpz(); + Fp12::pow(ea, e, a); + G1::mul(Pa, P, a); + G2::mul(Qa, Q, a); + G1 T; + G1::mulCT(T, P, a); + CYBOZU_TEST_EQUAL(Pa, T); + pairing(e1, Pa, Q); + pairing(e2, P, Qa); + CYBOZU_TEST_EQUAL(ea, e1); + CYBOZU_TEST_EQUAL(ea, e2); + } +} + +void testTrivial(const G1& P, const G2& Q) +{ + G1 Z1; Z1.clear(); + G2 Z2; Z2.clear(); + Fp12 e; + pairing(e, Z1, Q); + CYBOZU_TEST_EQUAL(e, 1); + pairing(e, P, Z2); + CYBOZU_TEST_EQUAL(e, 1); + pairing(e, Z1, Z2); + CYBOZU_TEST_EQUAL(e, 1); + + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Z2); + precomputedMillerLoop(e, P, Qcoeff); + finalExp(e, e); + CYBOZU_TEST_EQUAL(e, 1); + + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e, Z1, Qcoeff); + finalExp(e, e); + CYBOZU_TEST_EQUAL(e, 1); +} + +#include "bench.hpp" + +CYBOZU_TEST_AUTO(naive) +{ + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(g_testSetTbl); i++) { + const TestSet& ts = g_testSetTbl[i]; + printf("i=%d curve=%s\n", int(i), ts.name); + initPairing(ts.cp, g_mode); + const G1 P(Fp(ts.g1.a), Fp(ts.g1.b)); + const G2 Q(Fp2(ts.g2.aa, ts.g2.ab), Fp2(ts.g2.ba, ts.g2.bb)); +#ifdef ONLY_BENCH + { + Fp12 e; + for (int i = 0; i < 1000; i++) pairing(e, P, Q); + } + clk.put(); + return; +#endif + testParam(ts); + testIo(P, Q); +// testFp12pow(P, Q); + testTrivial(P, Q); + testSetStr(Q); + testMapToG1(); + testMapToG2(); + testPairing(P, Q, ts.e); + testPrecomputed(P, Q); + testMillerLoop2(P, Q); + testBench(P, Q); + } + int count = (int)clk.getCount(); + if (count) { + printf("count=%d ", count); + clk.put(); + } +} + +CYBOZU_TEST_AUTO(finalExp) +{ + const char *e0Str = +"012974491575E232199B73B30FE53FF643FEAE11023BCA7AF961C3600B45DFECFE4B30D52A62E73DA4C0409810304997\n" +"05CE2FB890FE65E20EC36347190ECB4884E401A64B666557B53E561F6D0979B7A96AD9E647ED78BD47187195C00F563C\n" +"02E85D1E559488603A70FEE99354DA8847215EC97282CA230DE96FED6DD5D4DD4EF4D901DB7F544A1A45EBEBA1450109\n" +"048FB1E44DDABF18D55C95704158A24678AA2A6ED0844108762E88306E5880E8C67BF44E24E40AB3F93D9E3713170341\n" +"07EF7BE685DC0DBA1B3E1D2E9090CD98EAD1325B60881772F17077386A3182B117F5FD839363F5891D08E82B88EC6F12\n" +"17803435700EF7A16C06404C6D17EB4FD84079FE9872207302A36C791B6E90447B33D703BBFE04ECB641C3A573E2CD50\n" +"19A494E6A872E46FC85D09FD6D30844B6FF05729BC253A9640F7BE64AAA8C2C8E0AE014A9DD816C53A3EDEBB2FA649EB\n" +"020949ABAA14F1DCE17FA9E091DDA963E9E492BA788E12B9B610E80A4D94DB9CC50341ED107C7D50E5738052595D4A27\n" +"09E217B513B3603723DAC3188A2F7CBDD84A56E7E5004446E7D4C63D6E378DA26E411C10898E48DB4B0C065E4699A9C5\n" +"12393BD23D0EC122082A1EC892A982F3C9AFD14240CE85258D8A3EF0A13CB545D6EF7848FD40DD4AEF1554341C5C5BBF\n" +"07EA8A0D6A57C78E5663F94E2B1ABC0D760ED18DBA64305EAD5EE350FB0342A7A81C0D5C8B3AD826D009276B0F32D2C8\n" +"16804D0D4A2633ED01568B0F8F06C4497E46E88D05FD191AAE530ACA791D0E114D74874FA88E33FAF48757153B09BB0E"; + +const char *e1Str = +"0E05D19E90D2C501E5502C7AC80D77201C47DF147DD1076440F0DF0179DF9802CA0775E0E73DD9174F1094D2280787B3\n" +"14D2F5C84279E7177A3543FBEAE261DE8F6C97EFD5F3FF3F959EC9FC0303F620A4B3AF00DF409496CECADDD0A7F0A164\n" +"1414E9B9DF8DF1EAC2E70D5538018377788C62016A54F28B037A68740705089AE431B86756F98CBE19690A5EAC0C2466\n" +"12D8B32157836A131CCA3CA313DAAAF909BC3AD6BDD15885BB429922B9CD7D1246D1163E5E6F88D68BF1B75E451EFABB\n" +"102C9A839A924E0D603D13F2E08A919E0B9EE2A269FC75727BA13D66027C157B9BB4077977FA94557DE4427BF11B234B\n" +"19DBEB7F2E3096AFFD44837655BD8249741B484B0EB0DBEE569DEA8D9E38AE09D210C8BC16AA6DFBC923095B2C9A8B2B\n" +"19B9A6DCCD01FA0D04D5CE94D8BDCE1DF64AFEB7FD493B955180A5C6B236E469F0E07CC9BB4203FCAC46AE6F8E5419D6\n" +"02BFA87AF7A3726A7ABACDCFDD53694AF651554F3A431AB4274F67D5DAD2D6C88AF794705FF456A936C83594731AD8DC\n" +"0F21E0173E3B50DD98EFA815B410631A57399B451FD6E1056FFD09C9FE50EFAD3D026F0C46C8BB1583A50B7853D990DA\n" +"02230237AE04B61F9269F6E7CD2FCF1231CEE4690AA658B0018EFC0D0770FD0A56B3B7294086E8D306B1465CDDD858CD\n" +"087EB8F6547015661E9CD48D6525C808636FCB8420B867CB2A87E006B2A93BBD5EF675E6CDDA9E6F94519C49EA8BB689\n" +"19F5C988B2DD6E33D7D3D34EFB1991F80DC28006AC75E0AB53FD98FC6F2476D05DD4ECA582F5FF72B8DDD9DDDE80FFC9"; + + Fp12 e0, e1, e2; + e0.setStr(e0Str, 16); + e1.setStr(e1Str, 16); + finalExp(e2, e0); +// finalExpC(e2, e0); + CYBOZU_TEST_EQUAL(e1, e2); + CYBOZU_BENCH_C("finalExp", 100, finalExp, e2, e0); +} + +CYBOZU_TEST_AUTO(addLine) +{ +const char *l0Str= +"0EF586FCDB69442CB41C0DA719AC5C92BD99A916C1F01BCFC7606AA7A23D680C04620FDFC2144E0EA6025F05241A791F\n" +"164CFDADE9B91150C6D2C7F7CDF29BC3105A7EA51217283CDF801EBEE9E86CE5078253E322C72129DAA42F6DBAD17D37"; +const char *l1Str = +"07A124F536BE83CCB3AF8D3DA2AE094942755040B9DA8E0796C462ACE3805D6916ACA7E9281261D8025571E2F31AAF0D\n" +"12D05751A9B255143541D0A4E57E120F937D51F9A07D31982390CA6EB5DF8CC0640FD291521069BF9964AE33EDD1323D"; +const char *l4Str = +"0D609DE41CF1260B332C1A53AA54703F62AB8224777E34FEEAB09AA06187CA71D8C7C2EB66F59D3622D431BE17D0FEE6\n" +"0A93C2984041171BE701560017D64D0640B6F61D7DCA8F527FA6B6A1A1033261C0761CAA56A00D4D16C9D3B7371E02D9"; + +const char *rStr = +"4 0A8DFA69FDD43EDCCC6375750373B443157EF4641E5B4CA82FBF23E3E8EA72351EA754168CEC77573D337E6227C0D0DD\n" +"12C8508CF1828C52A9A1A71779129D605327191EE459AED3C0B4B14657B08B2927173FADF8E4275188E8D49E57A75B33\n" +"12AD7EB96734F2C93B669FD54845CD2FF351AFDF0123E96772021DC3F4F3B456DB1B37CB1C380B1947616165FF0DDAEA\n" +"03D80F92C8A6005DEB291AF28406B7B4FCEDD81A244997DBB719B01D162BD7D71F0FD63BF76F8F1AC90618C3702294DF\n" +"199F7A719EA1CA2CD03CFFBB9A4BC2FE1BD8BCA7C772D223E6CB20C1313C3D3C52CFBB88445E56C833908C52A4EC68F1\n" +"0A3F6B27A6DDA00DB848574ECB06F179271D5844BDA66CD5AE1792A8FDD25E3A504A95839113BAA8B1FCB53EEE5F1FF0"; + +const char *qStr = +"4 0B5C339C23F8EAB3647E974BCDDF72C96F97A444346BE72CA73AB1323B83B8F6161257AB34C7E0CF34F6C45086CA5868\n" +"13C2235E9F9DFB33344BA2EE5A71435859022880732EDC9EC75AC79AE9DA972593CDC40A0AC334D6D2E8D7FAD1D98D0B\n" +"134B8EED8196A00D3B70ADBC26FF963B725A351CF0B73FE1A541788AFB0BB081AF82A438021B5E878B15D53B1D27C6A7\n" +"18CC69F847BEE826B939DCB4030D33020D03B046465C9EE103AA8009A175DB169070294E75771586687FE361DB884BCD\n" +"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n" +"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + +const char *pStr = +"4 0FD3977C60EC322BC281C915955ED534B491E39C72E8E800271CEF3F0492D890829FA69C45FCE93D9847A0CAB325D871\n" +"17CC2C36C5D283C05BFCECCF48DBB2050332DA058DD67326A9EE520967DBCAEDFCB5F05A085D1A49DF08BB968CC782C5\n" +"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"; + +const char *m0Str = +"1010A4F9944514352AAD5D290AFB95C435EB64B5E74519807C9602DABCD6B6F5494E419758AE9A43F539F812252C65E5\n" +"1622F7A52BAAC10EBFF0977F61866544BF9B91315FA66ADB6AC200AFF7A3676C1AD3480340B23C66F7C6AE50A703F245"; +const char *m1Str = +"0905180B20FCE2AA545A73D6B9EA1F82479EF3FB5A3BA8DDB656D9B2A4DA7B63CCF75538D15093949B442E27804C8CE2\n" +"0FE834508BBAD2F22DCBF1C3C1BCCD69561827613EB63F4907832A7ABBBC6040CF2E517D0D5E22D3812EEE1EC55640DD"; +const char *m4Str = +"1197D94A8DAFE6F72B17A31964CA5D0C3B2A12BEFF959F7DF7A37938C64C01508D12C24479E5C3D314F862A9977D6C7D\n" +"0B0254A26810307964E2A05680C19DE7C63CCBD7CC3558AD366BA48D9F7049E245BF2C54EA0339301739851E6EB2158F"; + +const char *r1Str = +"4 16A33C4ED01E95833D39EECE223380FE860B6DC1F71B1DDBEE2BE39B5D682B090F18758495E202010D3B9B45A46FF80E\n" +"01CECF5CC255E32B833C16EF3F983CCA9996A33504615909AD5685D9F637BF2357442BEC89DAFC747B69EFEF57D5A213\n" +"061C33850E5E4A418F3B68D6097C3911A551D6DB3C7E21196410F69D510C1A888635B6B699F98C14912A8D97742D36A9\n" +"0457FB78282C2B8F8BA803E77D058EF3BF6B06C6241D6FA6E2B1607F3E9D7597D1A10B7AA4E06B89FBA01736901AD826\n" +"0B45E9B7D311B8C37F7E9262227A4D721F2D148DE6F12EC5D599B45E4790F35B37A1D6928709F438849324A807EC1913\n" +"0E771545F892C247A5365BA1F14934D8ED37483A6B7DD3EB4C3FBA0AC884D7EE9C080C3B39ADA64AE545E7339F83AFB0"; + + const int mode = mcl::IoEcProj | 16; + Fp6 l, m; + G2 R, Q, R1; + G1 P; + + R.setStr(rStr, mode); + Q.setStr(qStr, mode); + P.setStr(pStr, mode); + l.a.setStr(l0Str, mode); + l.b.setStr(l4Str, mode); + l.c.setStr(l1Str, mode); + local::addLine(l, R, Q, P); + m.a.setStr(m0Str, mode); + m.b.setStr(m4Str, mode); + m.c.setStr(m1Str, mode); + R1.setStr(r1Str, mode); + CYBOZU_TEST_EQUAL(l, m); + CYBOZU_TEST_EQUAL(R, R1); +} + +CYBOZU_TEST_AUTO(dblLine) +{ +const char *l0Str= +"0905F47F07FA2177E4B73559D93D9B41A2FD20E0440167E63A0F62321EB73C784405DE360477245F5E4AE8FA2EAEC6FF\n" +"02DA455C573517EE8BD4E40A60851E2EC85CF514351681B89B1B72664E384A3678A25DC5C4CF84C086C13968BC701F91"; +const char *l1Str = +"0F48059E31CEF9546D41DEF31FB3BFD13BBCC38248E4846AFD216350B4B661FA1382E74BCF904BE8E33C26FF0D29ABA0\n" +"0D7FAEE426E4A6F32E4DE1CCB76BBA870A183113589CF58A358DC9C284C82B54C65A754F9A71EAD87304744CFD105051"; + +const char *l4Str = +"162AE8B029F8420BEDE5A399BA19C09FED01DE2748F4458065DBE51044FBFE749B28EF1B7F79A5E4545EB550DD0CFE02\n" +"091042B589FD59FBF286D21475CCCF444D8DCC49389EA3B98AF864DDB9C08BDDEB320D6D88F0C07D7CD1733A41404C1F"; + +const char *qStr = +"4 047ACF79048EDCA97A19DB1779A44CE610CEA9FDCC62D1C4014B335834BC63414F55B670CCF15A86E58BC3737FB70919\n" +"11D8063B2FFA2E1F5224593FF74D0E9650CAB6AF702B74159F7F97E2CF0843FBCD561D41FEC779BEB48746CD2F30FF74\n" +"17684E8EA85C990DF5472B4EBAF51002CDBBECF79BA2988FC610A5CE09F4A584248DCC506E78C39C9BB4F6008115DE64\n" +"1334CA7263ED9395BBEDBB6C938C642200C239FB0CADF1F652332A037FFBC7E567CCE09540939F25316CBC4FC68CE4DB\n" +"0670DCF344F027CB92F7B1F569B281C8FF756D83CD7B65EB118FE95FBE16ED28649B8F739FE3A2BECA1979FC18484ECD\n" +"13E3E30759DCC1FA9F1A62D54BEF0EE1CC75E194A559F2D6BE3025BE4BEB9F7351A7608FE8D4CCAD30BA2A8748205487"; + +const char *pStr = +"4 1579B48AE944AFE8FC69B38A7CD0D2C6B93E5F506535A5410E25FB1C1707938D6932F3D620A2BBB90ED7E2601971DEA8\n" +"0234E5B373AD62D9EF1EBAE6FA6FFAD26144717F65AE9F98BD4280978ED52B3621F60FA4A8F6E5B5DAF64469733827E6\n" +"0B4D1755924541041F75FF399E3B5F535BC85D5A982AEEC5FC2404F06AC7F062C090C4545D1602C3D8B559801EE7B9A2"; + +const char *m0Str = +"198D1123A9817C40A914A3FF9E29BB16DD2F0DF98D0AB5C3A6014D60E31AE973051C35ADCEA0A41F32BB16E6688DC73F\n" +"10339DB2F26D1B867FD3E60A24F938210EABEFC51536845A490F28A088A4AC53575DBBAA218D70D34E28EBDE14DB3465\n"; +const char *m1Str = +"066852248D915F6378B3F4A8E6173AC748FBFAE236AAEEAECC3F34D2D22706A06B925A83DD8276B2B240F61D761587B0\n" +"17CC8195E6607FF19A26AA69CA50C32487E35D2D75301AC4B6988F1B77523BF472927EE5710DF49A563534D86C684BE0\n"; +const char *m4Str = +"10B67D1A0CE430B7AD74F64DD6C2E44C4788EADF8340909843C96B918BF54703CC14686B26E350EB1140ACC3337EEEB4\n" +"0F5D52E6F0B10A081EFF885CC858109241B379985ADD8982E6B8A202FD283897EFBA4CBE444C29751410A61FC8346545"; + +const char *q1Str = +"4 17B5E51EC931E724ABACE9C7F8AFDD51F3929478B47C222F99844D166936063D3BFCDF7AD7079EEF4BE8514E3D09EF0F\n" +"0F5794F38BAEC0FA3C30AC4C0B8E9024B2047F2F4576434F91768F2B51AD58C48E88414B1D4B7A9119A947D3CFEDEF0A\n" +"1320714A8B7E23C4C558D2B1C556CC8FB6B41F3669EFD70B6D204C2A7C6EF2E0CBCA945AA7BACB402E00ED338F7D12FC\n" +"0C2846E386161F123344704528D9944677806C3F784E3997857C91D2F3F37AB6AD92360CD97CABD5D631E9FC74708AD3\n" +"17F92FF3D71B473B802F2DE90C19A5F5DBFAA397293871AB58E5B813F7D686EA8E1814C69C50C02D062F3A13C1D045E1\n" +"05214392858DE04B3B468B2D0C703A485508C29157D81E9F799BAB2FEF0F514C99D5F8085D8062281418C6CCE5621D18\n"; + + const int mode = mcl::IoEcProj | 16; + Fp6 l, m; + G2 Q, Q1; + G1 P; + + G1::setOrder(0); + Q.setStr(qStr, mode); + P.setStr(pStr, mode); + l.a.setStr(l0Str, mode); + l.b.setStr(l4Str, mode); + l.c.setStr(l1Str, mode); + local::dblLine(l, Q, P); + m.a.setStr(m0Str, mode); + m.b.setStr(m4Str, mode); + m.c.setStr(m1Str, mode); + Q1.setStr(q1Str, mode); + CYBOZU_TEST_EQUAL(l, m); + CYBOZU_TEST_EQUAL(Q, Q1); + G1::setOrder(BN::param.r); +} + +CYBOZU_TEST_AUTO(mul_012) +{ + const char *fStr = +"087590AFBFEB8F85DD912EC297C2B5DD7BC0A9B0914348C5D99F0089C09CDBA0DCDAF1C704A7B092D8FB9A75B7C06D88\n" +"119DD8B08C40D4EB3D7AF19221E41639A98A10EF1A22F9AD8CB1350526B9335F47E76B2FFD6652E693A67440574D5A0C\n" +"134ADA7C4ABFBA4324900D25E5077A119F9E55A7F337C03FD539D8DAC392B458F11261BEA007393D43657E9656B984D6\n" +"01032DDB3CAEC38B7DA916CA111C46A013F1DC83AF13DFF5B71CC3789974F946CFC43FE7B8EE519E524627248369FCE7\n" +"19E9455C14A9640139224BB1337E4EC5EE92BFF757DB179CC98CF0F09682E44ED4B6004F31D4788DE28BB2D8F41DDAE4\n" +"0B9877DF6AC1015375AB421363A5B06D2DC1763B923FF674A06AE101306A4A39967A3F9EF12E870C124A26CE68E2D003\n" +"02AA5AC5901C9C91CD0B43CA62F21FA541896802A8AAF0FD5EDF8DAF4A98CEC19F457A67369E795594543677B4A16EA4\n" +"0604DB7CE2A0ABD8ADB5F4F06F20B01510BF9787C912B1036F570E7368D341D9B794F078DFD3265306841180865500D0\n" +"08145045CF5751502778739EFE6FEA6036C8F14800F4818C2FD8BA5AF98E89B0BBE6510D511C4E5A83A2813A92B655F0\n" +"0FDE93D3326321ECF6171FBC4665F1C171F19A6F1D521BFA1A1B80E0B08CEBB78B255AF0B5F7E45AA6C1D01005200FB1\n" +"0F2A9EA2891A683AE15A79EDB0C6DF45FFAD4D22F3293AE59D3CE8F6E0E59A097673D05D81ACAD8C59817FFDD3E89CF1\n" +"0724BD07BDDCA23775C1DECD80CE7722F98C10E75A0CD9A1FA81921A04EEFAC55BE0740C5F01ED83FDFC66380339D417\n"; + +const char *l0Str = +"198D1123A9817C40A914A3FF9E29BB16DD2F0DF98D0AB5C3A6014D60E31AE973051C35ADCEA0A41F32BB16E6688DC73F\n" +"10339DB2F26D1B867FD3E60A24F938210EABEFC51536845A490F28A088A4AC53575DBBAA218D70D34E28EBDE14DB3465"; +const char *l1Str = +"066852248D915F6378B3F4A8E6173AC748FBFAE236AAEEAECC3F34D2D22706A06B925A83DD8276B2B240F61D761587B0\n" +"17CC8195E6607FF19A26AA69CA50C32487E35D2D75301AC4B6988F1B77523BF472927EE5710DF49A563534D86C684BE0\n"; +const char *l4Str = +"10B67D1A0CE430B7AD74F64DD6C2E44C4788EADF8340909843C96B918BF54703CC14686B26E350EB1140ACC3337EEEB4\n" +"0F5D52E6F0B10A081EFF885CC858109241B379985ADD8982E6B8A202FD283897EFBA4CBE444C29751410A61FC8346545\n"; + +const char *f2Str = +"10128E1A9BD00FC81F6550921D0FED3944F63F980ABF91FDB73B1ED162337ED16075730ACD60A0FA7DFABAD9FC9657C5\n" +"055BE26091D8CDA32241F4991A1F184E403C3FFDD54858B23D5CE4B44402B65B26BCA6855DA7AC1C60F1D6651632DCD8\n" +"0D70827981F0D33185DE8767FDDFEC26CEB6A28F82C83BBABB0057E432FCF9072B666974123274751E35F371E931D6CC\n" +"02382B1A80E5BC95C75AE71BE2E097FD59365279CDD7EA358D87DEF132430744DABBF1B685D110CC731A9FDA40EEFC1B\n" +"0AAB560FB99D57A9B1B6C753DAF6B0619ED598C9B5FB0908F2DAE83C530E6365DBEDE29B9357D63803F46247A1F41C73\n" +"13C048F553BFC3C56516786DD26FF9D59ECFB9BE6B165F90E77CCED623BC66C6E93EFBF14576DB7E33C8C4F4E21F64DC\n" +"0987D7DEBB96A10D977F256432871BEBB4B3A620E4AE822E089E9DAA192CD278E9FA0CF598444F6758628BC38C33A5AD\n" +"0A4F1B75845B6C976BF49C35134AE73CA7A3C16D2E0BDA39C70367E3829E94EB7CAFBB0F8B57F4734B696D9CEF84FE73\n" +"0DFAB9C035F3DA51226F27998A494A32245800F0313446D6437D2F5B3F34A9E91428818B0C9AF63EB3AA618E80055FD5\n" +"06A58B9640FF8931616F6D08BA16ECE71F341C61F22E5EC5B556DF217179C3ECEC20E4BE425A3471F1D6648D14F89FBF\n" +"1614391845CDC212937BC1070010603FB4DF99A6B3FA7E7CD3316C56BA8B633B3DC7D864B36DA2F9A1E6B977DB150100\n" +"144A44415BCCB077EAA64C8DAC50631AF432C1420EBD8538818D65D6176BC1EB699579CED8340493306AF842B4B6822E"; + + Fp6 l; + Fp12 f, f2; + l.a.setStr(l0Str, 16); + l.b.setStr(l4Str, 16); + l.c.setStr(l1Str, 16); + f.setStr(fStr, 16); + f2.setStr(f2Str, 16); + local::mulSparse(f, l); + CYBOZU_TEST_EQUAL(f, f2); +} + +CYBOZU_TEST_AUTO(pairing) +{ + const int mode = mcl::IoEcProj | 16; + +const char *pStr = +"4 0FD3977C60EC322BC281C915955ED534B491E39C72E8E800271CEF3F0492D890829FA69C45FCE93D9847A0CAB325D871\n" +"17CC2C36C5D283C05BFCECCF48DBB2050332DA058DD67326A9EE520967DBCAEDFCB5F05A085D1A49DF08BB968CC782C5\n" +"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"; +const char *qStr = +"4 0B5C339C23F8EAB3647E974BCDDF72C96F97A444346BE72CA73AB1323B83B8F6161257AB34C7E0CF34F6C45086CA5868\n" +"13C2235E9F9DFB33344BA2EE5A71435859022880732EDC9EC75AC79AE9DA972593CDC40A0AC334D6D2E8D7FAD1D98D0B\n" +"134B8EED8196A00D3B70ADBC26FF963B725A351CF0B73FE1A541788AFB0BB081AF82A438021B5E878B15D53B1D27C6A7\n" +"18CC69F847BEE826B939DCB4030D33020D03B046465C9EE103AA8009A175DB169070294E75771586687FE361DB884BCD\n" +"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n" +"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; +const char *eStr = +"0E05D19E90D2C501E5502C7AC80D77201C47DF147DD1076440F0DF0179DF9802CA0775E0E73DD9174F1094D2280787B3\n" +"14D2F5C84279E7177A3543FBEAE261DE8F6C97EFD5F3FF3F959EC9FC0303F620A4B3AF00DF409496CECADDD0A7F0A164\n" +"1414E9B9DF8DF1EAC2E70D5538018377788C62016A54F28B037A68740705089AE431B86756F98CBE19690A5EAC0C2466\n" +"12D8B32157836A131CCA3CA313DAAAF909BC3AD6BDD15885BB429922B9CD7D1246D1163E5E6F88D68BF1B75E451EFABB\n" +"102C9A839A924E0D603D13F2E08A919E0B9EE2A269FC75727BA13D66027C157B9BB4077977FA94557DE4427BF11B234B\n" +"19DBEB7F2E3096AFFD44837655BD8249741B484B0EB0DBEE569DEA8D9E38AE09D210C8BC16AA6DFBC923095B2C9A8B2B\n" +"19B9A6DCCD01FA0D04D5CE94D8BDCE1DF64AFEB7FD493B955180A5C6B236E469F0E07CC9BB4203FCAC46AE6F8E5419D6\n" +"02BFA87AF7A3726A7ABACDCFDD53694AF651554F3A431AB4274F67D5DAD2D6C88AF794705FF456A936C83594731AD8DC\n" +"0F21E0173E3B50DD98EFA815B410631A57399B451FD6E1056FFD09C9FE50EFAD3D026F0C46C8BB1583A50B7853D990DA\n" +"02230237AE04B61F9269F6E7CD2FCF1231CEE4690AA658B0018EFC0D0770FD0A56B3B7294086E8D306B1465CDDD858CD\n" +"087EB8F6547015661E9CD48D6525C808636FCB8420B867CB2A87E006B2A93BBD5EF675E6CDDA9E6F94519C49EA8BB689\n" +"19F5C988B2DD6E33D7D3D34EFB1991F80DC28006AC75E0AB53FD98FC6F2476D05DD4ECA582F5FF72B8DDD9DDDE80FFC9"; + G1 P; + G2 Q; + P.setStr(pStr, mode); + Q.setStr(qStr, mode); + Fp12 e1, e2; + e1.setStr(eStr, 16); + pairing(e2, P, Q); + CYBOZU_TEST_EQUAL(e1, e2); +} + +void testCurve(const mcl::CurveParam& cp) +{ + initPairing(cp, g_mode); + G1 P; + G2 Q; + mapToG1(P, 1); + mapToG2(Q, 1); + GT e1, e2; + pairing(e1, P, Q); + cybozu::XorShift rg; + mpz_class a, b; + Fr r; + r.setRand(rg); a = r.getMpz(); + r.setRand(rg); b = r.getMpz(); + G1 aP; + G2 bQ; + G1::mul(aP, P, a); + G2::mul(bQ, Q, b); + pairing(e2, aP, bQ); + GT::pow(e1, e1, a * b); + CYBOZU_TEST_EQUAL(e1, e2); +} +CYBOZU_TEST_AUTO(multi) +{ + G1 P; + G2 Q; + int i; + puts("BN254"); + testCurve(mcl::BN254); + i = 1; + CYBOZU_BENCH_C("calcBN1", 100, (BN::param.mapTo.calcBN<G1, Fp>), P, i++); + CYBOZU_BENCH_C("naiveG2", 100, (BN::param.mapTo.naiveMapTo<G1, Fp>), P, i++); + CYBOZU_BENCH_C("calcBN2", 100, (BN::param.mapTo.calcBN<G2, Fp2>), Q, i++); + CYBOZU_BENCH_C("naiveG2", 100, (BN::param.mapTo.naiveMapTo<G2, Fp2>), Q, i++); + puts("BLS12_381"); + testCurve(mcl::BLS12_381); + i = 1; + CYBOZU_BENCH_C("calcBN1", 100, (BN::param.mapTo.calcBN<G1, Fp>), P, i++); + CYBOZU_BENCH_C("naiveG1", 100, (BN::param.mapTo.naiveMapTo<G1, Fp>), P, i++); + CYBOZU_BENCH_C("calcBN2", 100, (BN::param.mapTo.calcBN<G2, Fp2>), Q, i++); + CYBOZU_BENCH_C("naiveG2", 100, (BN::param.mapTo.naiveMapTo<G2, Fp2>), Q, i++); +} + +CYBOZU_TEST_AUTO(BLS12_G1mulCofactor) +{ + if (BN::param.cp.curveType != MCL_BLS12_381) return; +} + +typedef std::vector<Fp> FpVec; + +void f(FpVec& zv, const FpVec& xv, const FpVec& yv) +{ + for (size_t i = 0; i < zv.size(); i++) { + Fp::mul(zv[i], xv[i], yv[i]); + } +} +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + std::string mode; + opt.appendOpt(&mode, "auto", "m", ": mode(gmp/gmp_mont/llvm/llvm_mont/xbyak)"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + g_mode = mcl::fp::StrToMode(mode); + printf("JIT %d\n", mcl::fp::isEnableJIT()); +#if 0 + initPairing(mcl::BLS12_381); + cybozu::XorShift rg; + const int n = 1; + std::vector<Fp> xv(n), yv(n), zv(n); + for (int i = 0; i < n; i++) { + xv[i].setByCSPRNG(rg); + yv[i].setByCSPRNG(rg); + } + FpDbl dx; + FpDbl::mulPre(dx, xv[0], yv[0]); + Fp2 x2, y2; + x2.a.setByCSPRNG(rg); + x2.b.setByCSPRNG(rg); + y2.a.setByCSPRNG(rg); + y2.b.setByCSPRNG(rg); + Fp2Dbl x2d, y2d; + Fp2Dbl::mulPre(x2d, x2, x2); + Fp2Dbl::mulPre(y2d, x2, y2); +if(0){ + puts("----------"); + xv[0].dump(); + yv[0].dump(); + dx.dump(); + puts("----------"); +// exit(1); +} +// CYBOZU_BENCH_C("Fp2::neg", 10000000, Fp2::neg, x2, x2); + CYBOZU_BENCH_C("Fp2::sqr", 10000000, Fp2::sqr, x2, x2); +// CYBOZU_BENCH_C("Fp2::sqrPre", 100000000, Fp2Dbl::sqrPre, x2d, x2); +// CYBOZU_BENCH_C("Fp2::mulPre", 100000000, Fp2Dbl::mulPre, x2d, x2, y2); +// CYBOZU_BENCH_C("sqrPre", 100000000, FpDbl::sqrPre, dx, xv[0]); +// CYBOZU_BENCH_C("mod ", 100000000, FpDbl::mod, xv[0], dx); +// CYBOZU_BENCH_C("mul ", 100000000, Fp::mul, xv[0], yv[0], xv[0]); +// CYBOZU_BENCH_C("sqr ", 100000000, Fp::sqr, xv[0], xv[0]); + return 0; +#endif + return cybozu::test::autoRun.run(argc, argv); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn384_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn384_test.cpp new file mode 100644 index 000000000..b5674a918 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn384_test.cpp @@ -0,0 +1,83 @@ +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> +#include <mcl/bn384.hpp> +#include <mcl/bn.hpp> + +using namespace mcl::bn384; + +mcl::fp::Mode g_mode; + +#include "bench.hpp" + +void testCurve(const mcl::CurveParam& cp) +{ + initPairing(cp, g_mode); + G1 P; + G2 Q; + mapToG1(P, 1); + mapToG2(Q, 1); + GT e1, e2; +#ifdef ONLY_BENCH + cybozu::CpuClock clk; + for (int i = 0; i < 10000; i++) { clk.begin(); pairing(e1, P, Q); clk.end(); } + clk.put(); + return; +#endif + pairing(e1, P, Q); + cybozu::XorShift rg; + mpz_class a, b; + Fr r; + r.setRand(rg); a = r.getMpz(); + r.setRand(rg); b = r.getMpz(); + G1 aP; + G2 bQ; + G1::mul(aP, P, a); + G2::mul(bQ, Q, b); + pairing(e2, aP, bQ); + GT::pow(e1, e1, a * b); + CYBOZU_TEST_EQUAL(e1, e2); + testBench(P, Q); + testSquareRoot(); + testLagrange(); +} + +CYBOZU_TEST_AUTO(pairing) +{ +// puts("BN160"); +// testCurve(mcl::BN160); + puts("BN254"); + // support 256-bit pairing + testCurve(mcl::BN254); + puts("BN381_1"); + testCurve(mcl::BN381_1); + puts("BN381_2"); + testCurve(mcl::BN381_2); + puts("BLS12_381"); + testCurve(mcl::BLS12_381); + // Q is not on EcT, but bad order + { + const char *s = "1 18d3d8c085a5a5e7553c3a4eb628e88b8465bf4de2612e35a0a4eb018fb0c82e9698896031e62fd7633ffd824a859474 1dc6edfcf33e29575d4791faed8e7203832217423bf7f7fbf1f6b36625b12e7132c15fbc15562ce93362a322fb83dd0d 65836963b1f7b6959030ddfa15ab38ce056097e91dedffd996c1808624fa7e2644a77be606290aa555cda8481cfb3cb 1b77b708d3d4f65aeedf54b58393463a42f0dc5856baadb5ce608036baeca398c5d9e6b169473a8838098fd72fd28b50"; + G2 Q; + CYBOZU_TEST_EXCEPTION(Q.setStr(s, 16), std::exception); + } +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + std::string mode; + opt.appendOpt(&mode, "auto", "m", ": mode(gmp/gmp_mont/llvm/llvm_mont/xbyak)"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + g_mode = mcl::fp::StrToMode(mode); + return cybozu::test::autoRun.run(argc, argv); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn512_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn512_test.cpp new file mode 100644 index 000000000..905bfd3db --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn512_test.cpp @@ -0,0 +1,68 @@ +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> +#include <mcl/bn512.hpp> +#include <mcl/bn.hpp> + +using namespace mcl::bn512; + +mcl::fp::Mode g_mode; + +#include "bench.hpp" + +void testCurve(const mcl::CurveParam& cp) +{ + initPairing(cp, g_mode); + G1 P; + G2 Q; + mapToG1(P, 1); + mapToG2(Q, 1); + GT e1, e2; + pairing(e1, P, Q); + cybozu::XorShift rg; + mpz_class a, b; + Fr r; + r.setRand(rg); a = r.getMpz(); + r.setRand(rg); b = r.getMpz(); + G1 aP; + G2 bQ; + G1::mul(aP, P, a); + G2::mul(bQ, Q, b); + pairing(e2, aP, bQ); + GT::pow(e1, e1, a * b); + CYBOZU_TEST_EQUAL(e1, e2); + testBench(P, Q); + testSquareRoot(); + testLagrange(); +} + +CYBOZU_TEST_AUTO(pairing) +{ + puts("BN462"); + testCurve(mcl::BN462); + puts("BN381_1"); + testCurve(mcl::BN381_1); + puts("BLS12_381"); + testCurve(mcl::BLS12_381); + puts("BN254"); + testCurve(mcl::BN254); +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + std::string mode; + opt.appendOpt(&mode, "auto", "m", ": mode(gmp/gmp_mont/llvm/llvm_mont/xbyak)"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + g_mode = mcl::fp::StrToMode(mode); + return cybozu::test::autoRun.run(argc, argv); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn_c256_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn_c256_test.cpp new file mode 100644 index 000000000..2ce85162d --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn_c256_test.cpp @@ -0,0 +1,6 @@ +#include <mcl/bn256.hpp> +using namespace mcl::bn256; +#define MCLBN_DEFINE_STRUCT +#define MCLBN_FP_UNIT_SIZE 4 +#include "bn_c_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn_c384_256_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn_c384_256_test.cpp new file mode 100644 index 000000000..e7bbefda9 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn_c384_256_test.cpp @@ -0,0 +1,7 @@ +#include <mcl/bls12_381.hpp> +using namespace mcl::bls12; +#define MCLBN_DEFINE_STRUCT +#define MCLBN_FP_UNIT_SIZE 6 +#define MCLBN_FR_UNIT_SIZE 4 +#include "bn_c_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn_c384_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn_c384_test.cpp new file mode 100644 index 000000000..a9f20243a --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn_c384_test.cpp @@ -0,0 +1,6 @@ +#include <mcl/bn384.hpp> +using namespace mcl::bn384; +#define MCLBN_DEFINE_STRUCT +#define MCLBN_FP_UNIT_SIZE 6 +#include "bn_c_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn_c512_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn_c512_test.cpp new file mode 100644 index 000000000..c6af3989f --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn_c512_test.cpp @@ -0,0 +1,6 @@ +#include <mcl/bn512.hpp> +using namespace mcl::bn512; +#define MCLBN_DEFINE_STRUCT +#define MCLBN_FP_UNIT_SIZE 8 +#include "bn_c_test.hpp" + diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn_c_test.hpp b/vendor/github.com/dexon-foundation/mcl/test/bn_c_test.hpp new file mode 100644 index 000000000..e9dc59393 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn_c_test.hpp @@ -0,0 +1,699 @@ +/* + include from bn_if256_test.cpp and bn_if384_test.cpp +*/ +#include <mcl/bn.h> +#include <mcl/ecparam.hpp> +#include <cybozu/test.hpp> +#include <iostream> +#include <gmpxx.h> + +template<size_t N> +std::ostream& dump(std::ostream& os, const uint64_t (&x)[N]) +{ + for (size_t i = 0; i < N; i++) { + char buf[64]; + CYBOZU_SNPRINTF(buf, sizeof(buf), "%016llx", (long long)x[i]); + os << buf; + } + return os; +} + +CYBOZU_TEST_AUTO(init) +{ + int ret; + CYBOZU_TEST_EQUAL(sizeof(mclBnFr), sizeof(Fr)); + CYBOZU_TEST_EQUAL(sizeof(mclBnG1), sizeof(G1)); + CYBOZU_TEST_EQUAL(sizeof(mclBnG2), sizeof(G2)); + CYBOZU_TEST_EQUAL(sizeof(mclBnGT), sizeof(Fp12)); + +#if MCLBN_FP_UNIT_SIZE >= 4 + printf("test BN254 %d\n", MCLBN_FP_UNIT_SIZE); + ret = mclBn_init(MCL_BN254, MCLBN_COMPILED_TIME_VAR); +#endif +#if MCLBN_FP_UNIT_SIZE >= 6 && MCLBN_FR_UNIT_SIZE >= 4 + printf("test BLS12_381 %d\n", MCLBN_FP_UNIT_SIZE); + ret = mclBn_init(MCL_BLS12_381, MCLBN_COMPILED_TIME_VAR); +#endif +#if MCLBN_FP_UNIT_SIZE >= 6 && MCLBN_FR_UNIT_SIZE >= 6 + printf("test BN381_1 %d\n", MCLBN_FP_UNIT_SIZE); + ret = mclBn_init(MCL_BN381_1, MCLBN_COMPILED_TIME_VAR); +#endif +#if MCLBN_FP_UNIT_SIZE == 8 + printf("test BN462 %d\n", MCLBN_FP_UNIT_SIZE); + ret = mclBn_init(MCL_BN462, MCLBN_COMPILED_TIME_VAR); +#endif + CYBOZU_TEST_EQUAL(ret, 0); + if (ret != 0) exit(1); +} + +CYBOZU_TEST_AUTO(Fr) +{ + mclBnFr x, y; + memset(&x, 0xff, sizeof(x)); + CYBOZU_TEST_ASSERT(!mclBnFr_isValid(&x)); + CYBOZU_TEST_ASSERT(!mclBnFr_isZero(&x)); + + mclBnFr_clear(&x); + CYBOZU_TEST_ASSERT(mclBnFr_isZero(&x)); + + mclBnFr_setInt(&x, 1); + CYBOZU_TEST_ASSERT(mclBnFr_isOne(&x)); + + mclBnFr_setInt(&y, -1); + CYBOZU_TEST_ASSERT(!mclBnFr_isEqual(&x, &y)); + + y = x; + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x, &y)); + + mclBnFr_setHashOf(&x, "", 0); + mclBnFr_setHashOf(&y, "abc", 3); + CYBOZU_TEST_ASSERT(!mclBnFr_isEqual(&x, &y)); + mclBnFr_setHashOf(&x, "abc", 3); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x, &y)); + + char buf[1024]; + mclBnFr_setInt(&x, 12345678); + size_t size; + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 8); + CYBOZU_TEST_EQUAL(buf, "12345678"); + + mclBnFr_setInt(&x, -7654321); + mclBnFr_neg(&x, &x); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 7); + CYBOZU_TEST_EQUAL(buf, "7654321"); + + mclBnFr_setInt(&y, 123 - 7654321); + mclBnFr_add(&x, &x, &y); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 3); + CYBOZU_TEST_EQUAL(buf, "123"); + + mclBnFr_setInt(&y, 100); + mclBnFr_sub(&x, &x, &y); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 2); + CYBOZU_TEST_EQUAL(buf, "23"); + + mclBnFr_mul(&x, &x, &y); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 4); + CYBOZU_TEST_EQUAL(buf, "2300"); + + mclBnFr_div(&x, &x, &y); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 2); + CYBOZU_TEST_EQUAL(buf, "23"); + + mclBnFr_mul(&x, &y, &y); + mclBnFr_sqr(&y, &y); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x, &y)); + + const char *s = "12345678901234567"; + CYBOZU_TEST_ASSERT(!mclBnFr_setStr(&x, s, strlen(s), 10)); + s = "20000000000000000"; + CYBOZU_TEST_ASSERT(!mclBnFr_setStr(&y, s, strlen(s), 10)); + mclBnFr_add(&x, &x, &y); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_EQUAL(size, 17); + CYBOZU_TEST_EQUAL(buf, "32345678901234567"); + + mclBnFr_setInt(&x, 1); + mclBnFr_neg(&x, &x); + size = mclBnFr_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_ASSERT(!mclBnFr_setStr(&y, buf, size, 10)); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x, &y)); + + for (int i = 0; i < 10; i++) { + mclBnFr_setByCSPRNG(&x); + mclBnFr_getStr(buf, sizeof(buf), &x, 16); + printf("%s\n", buf); + } +} + +void G1test() +{ + mclBnG1 x, y, z; + memset(&x, 0x1, sizeof(x)); + /* + assert() of carry operation fails if use 0xff, so use 0x1 + */ + CYBOZU_TEST_ASSERT(!mclBnG1_isValid(&x)); + mclBnG1_clear(&x); + CYBOZU_TEST_ASSERT(mclBnG1_isValid(&x)); + CYBOZU_TEST_ASSERT(mclBnG1_isZero(&x)); + + CYBOZU_TEST_ASSERT(!mclBnG1_hashAndMapTo(&y, "abc", 3)); + CYBOZU_TEST_ASSERT(mclBnG1_isValidOrder(&y)); + + char buf[1024]; + size_t size; + size = mclBnG1_getStr(buf, sizeof(buf), &y, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_ASSERT(!mclBnG1_setStr(&x, buf, strlen(buf), 10)); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&x, &y)); + + mclBnG1_neg(&x, &x); + mclBnG1_add(&x, &x, &y); + CYBOZU_TEST_ASSERT(mclBnG1_isZero(&x)); + + mclBnG1_dbl(&x, &y); // x = 2y + mclBnG1_add(&z, &y, &y); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&x, &z)); + mclBnG1_add(&z, &z, &y); // z = 3y + mclBnFr n; + mclBnFr_setInt(&n, 3); + mclBnG1_mul(&x, &y, &n); // x = 3y + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&x, &z)); + mclBnG1_sub(&x, &x, &y); // x = 2y + + mclBnFr_setInt(&n, 2); + mclBnG1_mul(&z, &y, &n); // z = 2y + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&x, &z)); + mclBnG1_normalize(&y, &z); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&y, &z)); +} + +CYBOZU_TEST_AUTO(G1) +{ + G1test(); +} + +CYBOZU_TEST_AUTO(G2) +{ + mclBnG2 x, y, z; + /* + assert() of carry operation fails if use 0xff, so use 0x1 + */ + memset(&x, 0x1, sizeof(x)); + CYBOZU_TEST_ASSERT(!mclBnG2_isValid(&x)); + mclBnG2_clear(&x); + CYBOZU_TEST_ASSERT(mclBnG2_isValid(&x)); + CYBOZU_TEST_ASSERT(mclBnG2_isZero(&x)); + + CYBOZU_TEST_ASSERT(!mclBnG2_hashAndMapTo(&x, "abc", 3)); + CYBOZU_TEST_ASSERT(mclBnG2_isValidOrder(&x)); + + char buf[1024]; + size_t size; + size = mclBnG2_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_ASSERT(!mclBnG2_setStr(&y, buf, strlen(buf), 10)); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&x, &y)); + + mclBnG2_neg(&x, &x); + mclBnG2_add(&x, &x, &y); + CYBOZU_TEST_ASSERT(mclBnG2_isZero(&x)); + + mclBnG2_dbl(&x, &y); // x = 2y + mclBnG2_add(&z, &y, &y); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&x, &z)); + mclBnG2_add(&z, &z, &y); // z = 3y + mclBnFr n; + mclBnFr_setInt(&n, 3); + mclBnG2_mul(&x, &y, &n); // x = 3y + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&x, &z)); + mclBnG2_sub(&x, &x, &y); // x = 2y + + mclBnFr_setInt(&n, 2); + mclBnG2_mul(&z, &y, &n); // z = 2y + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&x, &z)); + mclBnG2_normalize(&y, &z); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&y, &z)); +} + +CYBOZU_TEST_AUTO(GT) +{ + mclBnGT x, y, z; + memset(&x, 1, sizeof(x)); + CYBOZU_TEST_ASSERT(!mclBnGT_isZero(&x)); + + mclBnGT_clear(&x); + CYBOZU_TEST_ASSERT(mclBnGT_isZero(&x)); + + mclBnGT_setInt(&x, 1); + CYBOZU_TEST_ASSERT(mclBnGT_isOne(&x)); + char buf[2048]; + size_t size; + size = mclBnGT_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + const char *s = "1 0 0 0 0 0 0 0 0 0 0 0"; + CYBOZU_TEST_EQUAL(buf, s); + + s = "1 2 3 4 5 6 7 8 9 10 11 12"; + CYBOZU_TEST_ASSERT(!mclBnGT_setStr(&x,s , strlen(s), 10)); + size = mclBnGT_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_EQUAL(buf, s); + + y = x; + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&x, &y)); + + s = "-1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12"; + CYBOZU_TEST_ASSERT(!mclBnGT_setStr(&z, s, strlen(s), 10)); + size = mclBnGT_getStr(buf, sizeof(buf), &z, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_ASSERT(!mclBnGT_setStr(&y, buf, size, 10)); + + mclBnGT_neg(&z, &y); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&x, &z)); + + mclBnGT_add(&y, &x, &y); + CYBOZU_TEST_ASSERT(mclBnGT_isZero(&y)); + + s = "2 0 0 0 0 0 0 0 0 0 0 0"; + CYBOZU_TEST_ASSERT(!mclBnGT_setStr(&y, s, strlen(s), 10)); + mclBnGT_mul(&z, &x, &y); + size = mclBnGT_getStr(buf, sizeof(buf), &z, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_EQUAL(buf, "2 4 6 8 10 12 14 16 18 20 22 24"); + + mclBnGT_div(&z, &z, &y); + size = mclBnGT_getStr(buf, sizeof(buf), &x, 10); + CYBOZU_TEST_ASSERT(size > 0); + CYBOZU_TEST_EQUAL(size, strlen(buf)); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&x, &z)); + + /* + can't use mclBnGT_pow because x is not in GT + */ + mclBnFr n; + mclBnFr_setInt(&n, 3); + mclBnGT_powGeneric(&z, &x, &n); + mclBnGT_mul(&y, &x, &x); + mclBnGT_mul(&y, &y, &x); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&y, &z)); + + mclBnGT_mul(&x, &y, &y); + mclBnGT_sqr(&y, &y); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&x, &y)); +} + +CYBOZU_TEST_AUTO(pairing) +{ + mclBnFr a, b, ab; + mclBnFr_setInt(&a, 123); + mclBnFr_setInt(&b, 456); + mclBnFr_mul(&ab, &a, &b); + mclBnG1 P, aP; + mclBnG2 Q, bQ; + mclBnGT e, e1, e2; + + CYBOZU_TEST_ASSERT(!mclBnG1_hashAndMapTo(&P, "1", 1)); + CYBOZU_TEST_ASSERT(!mclBnG2_hashAndMapTo(&Q, "1", 1)); + + mclBnG1_mul(&aP, &P, &a); + mclBnG2_mul(&bQ, &Q, &b); + + mclBn_pairing(&e, &P, &Q); + mclBnGT_pow(&e1, &e, &a); + mclBn_pairing(&e2, &aP, &Q); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&e1, &e2)); + + mclBnGT_pow(&e1, &e, &b); + mclBn_pairing(&e2, &P, &bQ); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&e1, &e2)); + + mclBnFr n; + mclBnFr_setInt(&n, 3); + mclBnGT_pow(&e1, &e, &n); + mclBnGT_mul(&e2, &e, &e); + mclBnGT_mul(&e2, &e2, &e); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&e1, &e2)); +} + +CYBOZU_TEST_AUTO(precomputed) +{ + mclBnG1 P1, P2; + mclBnG2 Q1, Q2; + CYBOZU_TEST_ASSERT(!mclBnG1_hashAndMapTo(&P1, "1", 1)); + CYBOZU_TEST_ASSERT(!mclBnG1_hashAndMapTo(&P2, "123", 3)); + CYBOZU_TEST_ASSERT(!mclBnG2_hashAndMapTo(&Q1, "1", 1)); + CYBOZU_TEST_ASSERT(!mclBnG2_hashAndMapTo(&Q2, "2", 1)); + + const int size = mclBn_getUint64NumToPrecompute(); + std::vector<uint64_t> Q1buf, Q2buf; + Q1buf.resize(size); + Q2buf.resize(size); + mclBn_precomputeG2(Q1buf.data(), &Q1); + mclBn_precomputeG2(Q2buf.data(), &Q2); + + mclBnGT e1, e2, f1, f2, f3, f4; + mclBn_pairing(&e1, &P1, &Q1); + mclBn_precomputedMillerLoop(&f1, &P1, Q1buf.data()); + mclBn_finalExp(&f1, &f1); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&e1, &f1)); + + mclBn_pairing(&e2, &P2, &Q2); + mclBn_precomputedMillerLoop(&f2, &P2, Q2buf.data()); + mclBn_finalExp(&f2, &f2); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&e2, &f2)); + + mclBn_precomputedMillerLoop2(&f3, &P1, Q1buf.data(), &P2, Q2buf.data()); + mclBn_precomputedMillerLoop2mixed(&f4, &P1, &Q1, &P2, Q2buf.data()); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&f3, &f4)); + mclBn_finalExp(&f3, &f3); + + mclBnGT_mul(&e1, &e1, &e2); + CYBOZU_TEST_ASSERT(mclBnGT_isEqual(&e1, &f3)); +} + +CYBOZU_TEST_AUTO(serialize) +{ + const size_t FrSize = mclBn_getFrByteSize(); + const size_t G1Size = mclBn_getG1ByteSize(); + mclBnFr x1, x2; + mclBnG1 P1, P2; + mclBnG2 Q1, Q2; + char buf[1024]; + size_t n; + size_t expectSize; + size_t ret; + // Fr + expectSize = FrSize; + mclBnFr_setInt(&x1, -1); + n = mclBnFr_serialize(buf, sizeof(buf), &x1); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = mclBnFr_deserialize(&x2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x1, &x2)); + + ret = mclBnFr_deserialize(&x2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&x2, 0, sizeof(x2)); + ret = mclBnFr_deserialize(&x2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x1, &x2)); + + n = mclBnFr_serialize(buf, expectSize, &x1); + CYBOZU_TEST_EQUAL(n, expectSize); + + // G1 + expectSize = G1Size; + mclBnG1_hashAndMapTo(&P1, "1", 1); + n = mclBnG1_serialize(buf, sizeof(buf), &P1); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = mclBnG1_deserialize(&P2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&P1, &P2)); + + ret = mclBnG1_deserialize(&P2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&P2, 0, sizeof(P2)); + ret = mclBnG1_deserialize(&P2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&P1, &P2)); + + n = mclBnG1_serialize(buf, expectSize, &P1); + CYBOZU_TEST_EQUAL(n, expectSize); + + // G2 + expectSize = G1Size * 2; + mclBnG2_hashAndMapTo(&Q1, "1", 1); + n = mclBnG2_serialize(buf, sizeof(buf), &Q1); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = mclBnG2_deserialize(&Q2, buf, n); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&Q1, &Q2)); + + ret = mclBnG2_deserialize(&Q2, buf, n - 1); + CYBOZU_TEST_EQUAL(ret, 0); + + memset(&Q2, 0, sizeof(Q2)); + ret = mclBnG2_deserialize(&Q2, buf, n + 1); + CYBOZU_TEST_EQUAL(ret, n); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&Q1, &Q2)); + + n = mclBnG2_serialize(buf, expectSize, &Q1); + CYBOZU_TEST_EQUAL(n, expectSize); +} + +CYBOZU_TEST_AUTO(serializeToHexStr) +{ + const size_t FrSize = mclBn_getFrByteSize(); + const size_t G1Size = mclBn_getG1ByteSize(); + mclBnFr x1, x2; + mclBnG1 P1, P2; + mclBnG2 Q1, Q2; + char buf[1024]; + size_t n; + size_t expectSize; + size_t ret; + // Fr + expectSize = FrSize * 2; // hex string + mclBnFr_setInt(&x1, -1); + n = mclBnFr_getStr(buf, sizeof(buf), &x1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = mclBnFr_setStr(&x2, buf, n, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x1, &x2)); + + ret = mclBnFr_setStr(&x2, buf, n - 1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_ASSERT(ret != 0); + + memset(&x2, 0, sizeof(x2)); + ret = mclBnFr_setStr(&x2, buf, n + 1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&x1, &x2)); + + n = mclBnFr_getStr(buf, expectSize, &x1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(n, expectSize); + + // G1 + expectSize = G1Size * 2; // hex string + mclBnG1_hashAndMapTo(&P1, "1", 1); + n = mclBnG1_getStr(buf, sizeof(buf), &P1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = mclBnG1_setStr(&P2, buf, n, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&P1, &P2)); + + ret = mclBnG1_setStr(&P2, buf, n - 1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_ASSERT(ret != 0); + + memset(&P2, 0, sizeof(P2)); + ret = mclBnG1_setStr(&P2, buf, n + 1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&P1, &P2)); + + n = mclBnG1_getStr(buf, expectSize, &P1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(n, expectSize); + + // G2 + expectSize = G1Size * 2 * 2; // hex string + mclBnG2_hashAndMapTo(&Q1, "1", 1); + n = mclBnG2_getStr(buf, sizeof(buf), &Q1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(n, expectSize); + + ret = mclBnG2_setStr(&Q2, buf, n, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&Q1, &Q2)); + + ret = mclBnG2_setStr(&Q2, buf, n - 1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_ASSERT(ret != 0); + + memset(&Q2, 0, sizeof(Q2)); + ret = mclBnG2_setStr(&Q2, buf, n + 1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(ret, 0); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&Q1, &Q2)); + + n = mclBnG2_getStr(buf, expectSize, &Q1, MCLBN_IO_SERIALIZE_HEX_STR); + CYBOZU_TEST_EQUAL(n, expectSize); +} + +#if MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE >= 6 +CYBOZU_TEST_AUTO(badG2) +{ + int ret; + ret = mclBn_init(MCL_BN381_1, MCLBN_COMPILED_TIME_VAR); + CYBOZU_TEST_EQUAL(ret, 0); + const char *s = "1 18d3d8c085a5a5e7553c3a4eb628e88b8465bf4de2612e35a0a4eb018fb0c82e9698896031e62fd7633ffd824a859474 1dc6edfcf33e29575d4791faed8e7203832217423bf7f7fbf1f6b36625b12e7132c15fbc15562ce93362a322fb83dd0d 65836963b1f7b6959030ddfa15ab38ce056097e91dedffd996c1808624fa7e2644a77be606290aa555cda8481cfb3cb 1b77b708d3d4f65aeedf54b58393463a42f0dc5856baadb5ce608036baeca398c5d9e6b169473a8838098fd72fd28b50"; + mclBnG2 Q; + ret = mclBnG2_setStr(&Q, s, strlen(s), 16); + CYBOZU_TEST_ASSERT(ret != 0); +} +#endif + +struct Sequential { + uint32_t pos; + Sequential() : pos(0) {} + static uint32_t read(void *self, void *buf, uint32_t bufSize) + { + Sequential *seq = reinterpret_cast<Sequential*>(self); + uint8_t *p = reinterpret_cast<uint8_t*>(buf); + for (uint32_t i = 0; i < bufSize; i++) { + p[i] = uint8_t(seq->pos + i) & 0x1f; // mask is to make valid Fp + } + seq->pos += bufSize; + return bufSize; + } +}; + +CYBOZU_TEST_AUTO(setRandFunc) +{ + Sequential seq; + for (int j = 0; j < 3; j++) { + puts(j == 1 ? "sequential rand" : "true rand"); + for (int i = 0; i < 5; i++) { + mclBnFr x; + int ret; + char buf[1024]; + ret = mclBnFr_setByCSPRNG(&x); + CYBOZU_TEST_EQUAL(ret, 0); + ret = mclBnFr_getStr(buf, sizeof(buf), &x, 16); + CYBOZU_TEST_ASSERT(ret > 0); + printf("%d %s\n", i, buf); + } + if (j == 0) { + mclBn_setRandFunc(&seq, Sequential::read); + } else { + mclBn_setRandFunc(0, 0); + } + } +} + +CYBOZU_TEST_AUTO(Fp) +{ + mclBnFp x1, x2; + char buf[1024]; + int ret = mclBnFp_setHashOf(&x1, "abc", 3); + CYBOZU_TEST_ASSERT(ret == 0); + mclSize n = mclBnFp_serialize(buf, sizeof(buf), &x1); + CYBOZU_TEST_ASSERT(n > 0); + n = mclBnFp_deserialize(&x2, buf, n); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_ASSERT(mclBnFp_isEqual(&x1, &x2)); + for (size_t i = 0; i < n; i++) { + buf[i] = char(i); + } + ret = mclBnFp_setLittleEndian(&x1, buf, n); + CYBOZU_TEST_ASSERT(ret == 0); + memset(buf, 0, sizeof(buf)); + n = mclBnFp_serialize(buf, sizeof(buf), &x1); + CYBOZU_TEST_ASSERT(n > 0); + for (size_t i = 0; i < n - 1; i++) { + CYBOZU_TEST_EQUAL(buf[i], char(i)); + } + mclBnFp_clear(&x1); + memset(&x2, 0, sizeof(x2)); + CYBOZU_TEST_ASSERT(mclBnFp_isEqual(&x1, &x2)); +} + +CYBOZU_TEST_AUTO(mod) +{ + { + // Fp + char buf[1024]; + mclBn_getFieldOrder(buf, sizeof(buf)); + mpz_class p(buf); + mpz_class x = mpz_class(1) << (mclBn_getFpByteSize() * 2); + mclBnFp y; + int ret = mclBnFp_setLittleEndianMod(&y, x.get_mpz_t()->_mp_d, x.get_mpz_t()->_mp_size * sizeof(void*)); + CYBOZU_TEST_EQUAL(ret, 0); + mclBnFp_getStr(buf, sizeof(buf), &y, 10); + CYBOZU_TEST_EQUAL(mpz_class(buf), x % p); + } + { + // Fr + char buf[1024]; + mclBn_getCurveOrder(buf, sizeof(buf)); + mpz_class p(buf); + mpz_class x = mpz_class(1) << (mclBn_getFrByteSize() * 2); + mclBnFr y; + int ret = mclBnFr_setLittleEndianMod(&y, x.get_mpz_t()->_mp_d, x.get_mpz_t()->_mp_size * sizeof(void*)); + CYBOZU_TEST_EQUAL(ret, 0); + mclBnFr_getStr(buf, sizeof(buf), &y, 10); + CYBOZU_TEST_EQUAL(mpz_class(buf), x % p); + } +} + +CYBOZU_TEST_AUTO(Fp2) +{ + mclBnFp2 x1, x2; + char buf[1024]; + int ret = mclBnFp_setHashOf(&x1.d[0], "abc", 3); + CYBOZU_TEST_ASSERT(ret == 0); + ret = mclBnFp_setHashOf(&x1.d[1], "xyz", 3); + CYBOZU_TEST_ASSERT(ret == 0); + mclSize n = mclBnFp2_serialize(buf, sizeof(buf), &x1); + CYBOZU_TEST_ASSERT(n > 0); + n = mclBnFp2_deserialize(&x2, buf, n); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&x1, &x2)); + mclBnFp2_clear(&x1); + memset(&x2, 0, sizeof(x2)); + CYBOZU_TEST_ASSERT(mclBnFp2_isEqual(&x1, &x2)); +} + +CYBOZU_TEST_AUTO(mapToG1) +{ + mclBnFp x; + mclBnG1 P1, P2; + mclBnFp_setHashOf(&x, "abc", 3); + int ret = mclBnFp_mapToG1(&P1, &x); + CYBOZU_TEST_ASSERT(ret == 0); + mclBnG1_hashAndMapTo(&P2, "abc", 3); + CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&P1, &P2)); +} + +CYBOZU_TEST_AUTO(mapToG2) +{ + mclBnFp2 x; + mclBnG2 P1, P2; + mclBnFp_setHashOf(&x.d[0], "abc", 3); + mclBnFp_clear(&x.d[1]); + int ret = mclBnFp2_mapToG2(&P1, &x); + CYBOZU_TEST_ASSERT(ret == 0); + mclBnG2_hashAndMapTo(&P2, "abc", 3); + CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&P1, &P2)); +} + +void G1onlyTest(int curve) +{ + printf("curve=%d\n", curve); + int ret; + ret = mclBn_init(curve, MCLBN_COMPILED_TIME_VAR); + CYBOZU_TEST_EQUAL(ret, 0); + mclBnG1 P0; + ret = mclBnG1_getBasePoint(&P0); + CYBOZU_TEST_EQUAL(ret, 0); + char buf[256]; + ret = mclBnG1_getStr(buf, sizeof(buf), &P0, 16); + CYBOZU_TEST_ASSERT(ret > 0); + printf("basePoint=%s\n", buf); + G1test(); +} + +CYBOZU_TEST_AUTO(G1only) +{ + const int tbl[] = { + MCL_SECP192K1, + MCL_NIST_P192, + MCL_SECP224K1, + MCL_NIST_P224, // hashAndMapTo is error + MCL_SECP256K1, + MCL_NIST_P256, +#if MCLBN_FP_UNIT_SIZE >= 6 && MCLBN_FR_UNIT_SIZE >= 6 + MCL_SECP384R1, +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + G1onlyTest(tbl[i]); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/bn_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/bn_test.cpp new file mode 100644 index 000000000..071ec706c --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/bn_test.cpp @@ -0,0 +1,408 @@ +#define PUT(x) std::cout << #x "=" << x << std::endl; +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/benchmark.hpp> +cybozu::CpuClock clk; +#include <cybozu/test.hpp> +#include <mcl/bn256.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> + +#if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST) + #define MCL_AVOID_EXCEPTION_TEST +#endif + +typedef mcl::bn::local::Compress Compress; +using namespace mcl::bn; + +mcl::fp::Mode g_mode; + +const struct TestSet { + mcl::CurveParam cp; + const char *name; + struct G2 { + const char *aa; + const char *ab; + const char *ba; + const char *bb; + } g2; + struct G1 { + int a; + int b; + } g1; + const char *e; +} g_testSetTbl[] = { + { + mcl::BN254, + "BN254", + { + "12723517038133731887338407189719511622662176727675373276651903807414909099441", + "4168783608814932154536427934509895782246573715297911553964171371032945126671", + "13891744915211034074451795021214165905772212241412891944830863846330766296736", + "7937318970632701341203597196594272556916396164729705624521405069090520231616", + }, + { + -1, 1 + }, + "8118772341496577043438385328606447626730215814727396173233264007541007797690 " + "6742571767760762192519140673058087976840103832045324348366170860928670686713 " + "9727912590495366720378364920530546614235713408261568635512172059018197267630 " + "10180700148605185348549931182990442059136187839792856455707820203302941578832 " + "5054507763444412917986776641611331046146804026682679569910978464879371792565 " + "6917005519826733659554708445125877487590687705432214234949972860245110398023 " + "10448556317747236258066222816126375978842661908560317699736569642190930635294 " + "1516980358051268127904344653343215863076753141133525905743113718749531324025 " + "9794836735385959178744195210089532061310424844916928682580569566332541022353 " + "9375574834170998962484906689780052970915033987453510324648351251071086068423 " + "710778048594563655498360873129325895716179849942646859397874562033386335205 " + "10688745994254573144943003027511098295097561129365638275727908595677791826005" + }, + { + mcl::BN_SNARK1, + "BN_SNARK1", + { + "15267802884793550383558706039165621050290089775961208824303765753922461897946", + "9034493566019742339402378670461897774509967669562610788113215988055021632533", + "644888581738283025171396578091639672120333224302184904896215738366765861164", + "20532875081203448695448744255224543661959516361327385779878476709582931298750", + }, + { + 1, 2 + }, + "15163392945550945552839911839294582974434771053565812675833291179413834896953 " + "20389211011850518572149982239826345669421868561029856883955740401696801984953 " + "17766795911013516700216709333389761327222334145011922123798810516425387779347 " + "6064163297423711021549973931984064750876944939004405231004441199168710504090 " + "296093106139306574860102680862436174771023602986903675151017278048818344347 " + "1573596951222456889652521728261836933382094474023551133585236991207205981715 " + "3511871642997169996730611220058787939468653751355351269812083879279936651479 " + "17848534184080172844395614793152774197360421729995967636680357250333093768504 " + "3273860031361637906105800996652640969711942192883181518057117446820546419132 " + "7212721189663231589365009629980400132745687533815732336503876102977912682966 " + "18569236611881855981733896549089319395087993987737891870319625215675547032585 " + "10088832670068482545658647976676953228519838542958787800193793260459700064172 " + }, +}; + +CYBOZU_TEST_AUTO(size) +{ + CYBOZU_TEST_EQUAL(sizeof(Fp), 32u); + CYBOZU_TEST_EQUAL(sizeof(Fp2), sizeof(Fp) * 2); + CYBOZU_TEST_EQUAL(sizeof(Fp6), sizeof(Fp) * 6); + CYBOZU_TEST_EQUAL(sizeof(Fp12), sizeof(Fp) * 12); + CYBOZU_TEST_EQUAL(sizeof(G1), sizeof(Fp) * 3); + CYBOZU_TEST_EQUAL(sizeof(G2), sizeof(Fp2) * 3); +} + +void testSetStr(const G2& Q0) +{ + G2::setCompressedExpression(); + G2 Q; + Q.clear(); + for (int i = 0; i < 10; i++) { + G2 R; + R.setStr(Q.getStr()); + CYBOZU_TEST_EQUAL(Q, R); + G2::add(Q, Q, Q0); + } +} + +void testMapToG1() +{ + G1 g; + for (int i = 1; i < 10; i++) { + mapToG1(g, i); + CYBOZU_TEST_ASSERT(!g.isZero()); + G1 gr; + G1::mulGeneric(gr, g, BN::param.r); + CYBOZU_TEST_ASSERT(gr.isZero()); + } +#ifndef MCL_AVOID_EXCEPTION_TEST + if (BN::param.cp.b == 2) { + Fp c1; + bool b = Fp::squareRoot(c1, -3); + CYBOZU_TEST_ASSERT(b); + CYBOZU_TEST_EXCEPTION(mapToG1(g, 0), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(mapToG1(g, c1), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(mapToG1(g, -c1), cybozu::Exception); + } +#endif +} + +void testMapToG2() +{ + G2 g; + for (int i = 1; i < 10; i++) { + mapToG2(g, i); + CYBOZU_TEST_ASSERT(!g.isZero()); + G2 gr; + G2::mulGeneric(gr, g, BN::param.r); + CYBOZU_TEST_ASSERT(gr.isZero()); + } +#ifndef MCL_AVOID_EXCEPTION_TEST + if (BN::param.cp.b == 2) { + CYBOZU_TEST_EXCEPTION(mapToG2(g, 0), cybozu::Exception); + } +#endif + Fp x; + x.setHashOf("abc"); + mapToG2(g, Fp2(x, 0)); + CYBOZU_TEST_ASSERT(g.isValid()); +} + +void testCyclotomic() +{ + Fp12 a; + for (int i = 0; i < 12; ++i) { + a.getFp0()[i] = i * i; + } + local::mapToCyclotomic(a, a); + Fp12 d; + Compress b(d, a); + a *= a; + Fp12 d2; + Compress c(d2, b); + Compress::square_n(c, 1); + c.decompress(); + CYBOZU_TEST_EQUAL(a, d2); + Compress::square_n(b, 1); + b.decompress(); + CYBOZU_TEST_EQUAL(a, d); +} + +void testCompress(const G1& P, const G2& Q) +{ + if (BN::param.cp.curveType != MCL_BN254) return; + Fp12 a; + pairing(a, P, Q); + local::mapToCyclotomic(a, a); + Fp12 b; + Compress::fixed_power(b, a); + Fp12 c; + Fp12::pow(c, a, BN::param.abs_z); + CYBOZU_TEST_EQUAL(b, c); +} + +void testPrecomputed(const G1& P, const G2& Q) +{ + Fp12 e1, e2; + pairing(e1, P, Q); + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e2, P, Qcoeff); + finalExp(e2, e2); + CYBOZU_TEST_EQUAL(e1, e2); +} + +void testFp12pow(const G1& P, const G2& Q) +{ + Fp12 e, e1, e2; + pairing(e, P, Q); + cybozu::XorShift rg; + for (int i = -10; i < 10; i++) { + mpz_class xm = i; + Fp12::pow(e1, e, xm); + Fp12::powGeneric(e2, e, xm); + CYBOZU_TEST_EQUAL(e1, e2); + } + for (int i = 0; i < 10; i++) { + Fr x; + x.setRand(rg); + mpz_class xm = x.getMpz(); + Fp12::pow(e1, e, xm); + BN::param.glv2.pow(e2, e, xm); + CYBOZU_TEST_EQUAL(e1, e2); + } +} + +void testMillerLoop2(const G1& P1, const G2& Q1) +{ + Fp12 e1, e2, e3; + mpz_class c1("12342342423442"); + mpz_class c2("329428049820348209482"); + G2 Q2; + G1 P2; + G2::mul(Q2, Q1, c1); + G1::mul(P2, P1, c2); + pairing(e1, P1, Q1); + pairing(e2, P2, Q2); + e1 *= e2; + + std::vector<Fp6> Q1coeff, Q2coeff; + precomputeG2(Q1coeff, Q1); + precomputeG2(Q2coeff, Q2); + precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); + precomputedMillerLoop2mixed(e3, P1, Q1, P2, Q2coeff); + CYBOZU_TEST_EQUAL(e2, e3); + finalExp(e2, e2); + CYBOZU_TEST_EQUAL(e1, e2); + + // special value + G2 Z; + Z.clear(); + Q2 += Q2; + precomputeG2(Q1coeff, Z); + precomputeG2(Q2coeff, Q2); + precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); + precomputedMillerLoop2mixed(e3, P1, Z, P2, Q2coeff); + finalExp(e2, e2); + finalExp(e3, e3); + CYBOZU_TEST_EQUAL(e2, e3); +} + +void testPairing(const G1& P, const G2& Q, const char *eStr) +{ + Fp12 e1; + pairing(e1, P, Q); + Fp12 e2; + { + std::stringstream ss(eStr); + ss >> e2; + } + CYBOZU_TEST_EQUAL(e1, e2); + + Fp12 e = e1, ea; + G1 Pa; + G2 Qa; +#if defined(__EMSCRIPTEN__) || MCL_SIZEOF_UNIT == 4 + const int count = 100; +#else + const int count = 1000; +#endif + mpz_class a; + cybozu::XorShift rg; + for (int i = 0; i < count; i++) { + Fr r; + r.setRand(rg); + a = r.getMpz(); + Fp12::pow(ea, e, a); + G1::mul(Pa, P, a); + G2::mul(Qa, Q, a); + G1 T; + G1::mulCT(T, P, a); + CYBOZU_TEST_EQUAL(Pa, T); + pairing(e1, Pa, Q); + pairing(e2, P, Qa); + CYBOZU_TEST_EQUAL(ea, e1); + CYBOZU_TEST_EQUAL(ea, e2); + } +} + +void testTrivial(const G1& P, const G2& Q) +{ + G1 Z1; Z1.clear(); + G2 Z2; Z2.clear(); + Fp12 e; + pairing(e, Z1, Q); + CYBOZU_TEST_EQUAL(e, 1); + pairing(e, P, Z2); + CYBOZU_TEST_EQUAL(e, 1); + pairing(e, Z1, Z2); + CYBOZU_TEST_EQUAL(e, 1); + + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Z2); + precomputedMillerLoop(e, P, Qcoeff); + finalExp(e, e); + CYBOZU_TEST_EQUAL(e, 1); + + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e, Z1, Qcoeff); + finalExp(e, e); + CYBOZU_TEST_EQUAL(e, 1); +} + +void testIoAll(const G1& P, const G2& Q) +{ + const int FpTbl[] = { 0, 2, 2|mcl::IoPrefix, 10, 16, 16|mcl::IoPrefix, mcl::IoArray, mcl::IoArrayRaw }; + const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(FpTbl); i++) { + for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(EcTbl); j++) { + G1 P2 = P, P3; + G2 Q2 = Q, Q3; + int ioMode = FpTbl[i] | EcTbl[j]; + std::string s = P2.getStr(ioMode); + P3.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(P2, P3); + s = Q2.getStr(ioMode); + Q3.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(Q2, Q3); + s = P.x.getStr(ioMode); + Fp Px; + Px.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(P.x, Px); + s = Q.x.getStr(ioMode); + Fp2 Qx; + Qx.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(Q.x, Qx); + } + } +} + +void testIo(const G1& P, const G2& Q) +{ + testIoAll(P, Q); + G1 Z1; + G2 Z2; + Z1.clear(); + Z2.clear(); + testIoAll(Z1, Z2); +} + +#include "bench.hpp" + +CYBOZU_TEST_AUTO(naive) +{ + printf("mcl version=%03x\n", mcl::version); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(g_testSetTbl); i++) { + const TestSet& ts = g_testSetTbl[i]; + printf("i=%d curve=%s\n", int(i), ts.name); + initPairing(ts.cp, g_mode); + const G1 P(ts.g1.a, ts.g1.b); + const G2 Q(Fp2(ts.g2.aa, ts.g2.ab), Fp2(ts.g2.ba, ts.g2.bb)); +#ifdef ONLY_BENCH + { + Fp12 e; + for (int i = 0; i < 10000; i++) { clk.begin(); pairing(e, P, Q); clk.end(); } + } + clk.put(); + return; +#endif + testFp12pow(P, Q); + testIo(P, Q); + testTrivial(P, Q); + testSetStr(Q); + testMapToG1(); + testMapToG2(); + testCyclotomic(); + testCompress(P, Q); + testPairing(P, Q, ts.e); + testPrecomputed(P, Q); + testMillerLoop2(P, Q); + testBench(P, Q); + benchAddDblG1(); + benchAddDblG2(); + } + int count = (int)clk.getCount(); + if (count) { + printf("count=%d ", count); + clk.put(); + } +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + std::string mode; + opt.appendOpt(&mode, "auto", "m", ": mode(gmp/gmp_mont/llvm/llvm_mont/xbyak)"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + g_mode = mcl::fp::StrToMode(mode); + printf("JIT %d\n", mcl::fp::isEnableJIT()); + return cybozu::test::autoRun.run(argc, argv); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/conversion_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/conversion_test.cpp new file mode 100644 index 000000000..ec11fe900 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/conversion_test.cpp @@ -0,0 +1,96 @@ +#include <cybozu/test.hpp> +#include <mcl/conversion.hpp> + +CYBOZU_TEST_AUTO(arrayToDec) +{ + const struct { + uint32_t x[5]; + size_t xn; + const char *s; + } tbl[] = { + { { 0, 0, 0, 0, 0 }, 1, "0" }, + { { 9, 0, 0, 0, 0 }, 1, "9" }, + { { 123456789, 0, 0, 0, 0 }, 1, "123456789" }, + { { 2147483647, 0, 0, 0, 0 }, 1, "2147483647" }, + { { 0xffffffff, 0, 0, 0, 0 }, 1, "4294967295" }, + { { 0x540be400, 0x2, 0, 0, 0 }, 2, "10000000000" }, + { { 0xffffffff, 0xffffffff, 0, 0, 0 }, 2, "18446744073709551615" }, + { { 0x89e80001, 0x8ac72304, 0, 0, 0 }, 2, "10000000000000000001" }, + { { 0xc582ca00, 0x8ac72304, 0, 0, 0 }, 2, "10000000001000000000" }, + { { 0, 0, 1, 0, 0 }, 3, "18446744073709551616" }, + { { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0 }, 4, "340282366920938463463374607431768211455" }, + { { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, 5, "1461501637330902918203684832716283019655932542975" }, + { { 0x3b9aca00, 0x5e3f3700, 0x1cbfa532, 0x04f6433a, 0xd83ff078 }, 5, "1234567901234560000000000000000000000001000000000" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const size_t bufSize = 128; + char buf[bufSize] = {}; + const char *str = tbl[i].s; + const uint32_t *x = tbl[i].x; + const size_t strLen = strlen(str); + size_t n = mcl::fp::arrayToDec(buf, bufSize, x, tbl[i].xn); + CYBOZU_TEST_EQUAL(n, strLen); + CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n); + const size_t maxN = 32; + uint32_t xx[maxN] = {}; + size_t xn = mcl::fp::decToArray(xx, maxN, str, strLen); + CYBOZU_TEST_EQUAL(xn, tbl[i].xn); + CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn); + } + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const size_t bufSize = 128; + char buf[bufSize] = {}; + const char *str = tbl[i].s; + const size_t strLen = strlen(str); + uint64_t x[8] = {}; + size_t xn = (tbl[i].xn + 1) / 2; + memcpy(x, tbl[i].x, tbl[i].xn * sizeof(uint32_t)); + size_t n = mcl::fp::arrayToDec(buf, bufSize, x, xn); + CYBOZU_TEST_EQUAL(n, strLen); + CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n); + const size_t maxN = 32; + uint64_t xx[maxN] = {}; + size_t xxn = mcl::fp::decToArray(xx, maxN, str, strLen); + CYBOZU_TEST_EQUAL(xxn, xn); + CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn); + } +} + +CYBOZU_TEST_AUTO(writeHexStr) +{ + const char *hex1tbl = "0123456789abcdef"; + const char *hex2tbl = "0123456789ABCDEF"; + for (size_t i = 0; i < 16; i++) { + uint8_t v = 0xff; + CYBOZU_TEST_ASSERT(mcl::fp::local::hexCharToUint8(&v, hex1tbl[i])); + CYBOZU_TEST_EQUAL(v, i); + CYBOZU_TEST_ASSERT(mcl::fp::local::hexCharToUint8(&v, hex2tbl[i])); + CYBOZU_TEST_EQUAL(v, i); + } + const struct Tbl { + const char *bin; + size_t n; + const char *hex; + } tbl[] = { + { "", 0, "" }, + { "\x12\x34\xab", 3, "1234ab" }, + { "\xff\xfc\x00\x12", 4, "fffc0012" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + char buf[32]; + cybozu::MemoryOutputStream os(buf, sizeof(buf)); + const char *bin = tbl[i].bin; + const char *hex = tbl[i].hex; + size_t n = tbl[i].n; + bool b; + mcl::fp::writeHexStr(&b, os, bin, n); + CYBOZU_TEST_ASSERT(b); + CYBOZU_TEST_EQUAL(os.getPos(), n * 2); + CYBOZU_TEST_EQUAL_ARRAY(buf, hex, n * 2); + + cybozu::MemoryInputStream is(hex, n * 2); + size_t w = mcl::fp::readHexStr(buf, n, is); + CYBOZU_TEST_EQUAL(w, n); + CYBOZU_TEST_EQUAL_ARRAY(buf, bin, n); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/ec_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/ec_test.cpp new file mode 100644 index 000000000..ec49adbfe --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/ec_test.cpp @@ -0,0 +1,573 @@ +//#define MCL_EC_USE_AFFINE +#define PUT(x) std::cout << #x "=" << (x) << std::endl +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <mcl/gmp_util.hpp> + +#include <mcl/fp.hpp> +#include <mcl/ec.hpp> +#include <mcl/ecparam.hpp> +#include <time.h> +#include <math.h> + +typedef mcl::FpT<> Fp; +struct tagZn; +typedef mcl::FpT<tagZn> Zn; +typedef mcl::EcT<Fp> Ec; + +CYBOZU_TEST_AUTO(sizeof) +{ + CYBOZU_TEST_EQUAL(sizeof(Fp), sizeof(mcl::fp::Unit) * Fp::maxSize); +#ifdef MCL_EC_USE_AFFINE + CYBOZU_TEST_EQUAL(sizeof(Ec), sizeof(Fp) * 2 + sizeof(mcl::fp::Unit)); +#else + CYBOZU_TEST_EQUAL(sizeof(Ec), sizeof(Fp) * 3); +#endif +} + +struct Test { + const mcl::EcParam& para; + Test(const mcl::EcParam& para, mcl::fp::Mode fpMode, mcl::ec::Mode ecMode) + : para(para) + { + printf("fpMode=%s\n", mcl::fp::ModeToStr(fpMode)); + Fp::init(para.p, fpMode); + Zn::init(para.n, fpMode); + Ec::init(para.a, para.b, ecMode); + } + void cstr() const + { + Ec O; + O.clear(); + CYBOZU_TEST_ASSERT(O.isZero()); + CYBOZU_TEST_ASSERT(O.isValid()); + Ec P; + P.clear(); + Ec::neg(P, O); + CYBOZU_TEST_EQUAL(P, O); + } + void pow2(Ec& Q, const Ec& P, int n) const + { + Q = P; + for (int i = 0; i < n; i++) { + Q += Q; + } + } + void pow2test(const Ec& P, int n) const + { + Ec Q, R; + pow2(Q, P, n); + Q -= P; // Q = (2^n - 1)P + Fp x = 1; + for (int i = 0; i < n; i++) { + x += x; + } + x -= 1; // x = 2^n - 1 + Ec::mul(R, P, x); + CYBOZU_TEST_EQUAL(Q, R); + Q = P; + Ec::mul(Q, Q, x); + CYBOZU_TEST_EQUAL(Q, R); + } + void ope() const + { + Fp x(para.gx); + Fp y(para.gy); + Zn n = 0; + CYBOZU_TEST_NO_EXCEPTION(Ec(x, y)); + CYBOZU_TEST_EXCEPTION(Ec(x, y + 1), cybozu::Exception); + Ec P(x, y), Q, R, O; + O.clear(); + CYBOZU_TEST_ASSERT(P.isNormalized()); + { + Ec::neg(Q, P); + CYBOZU_TEST_EQUAL(Q.x, P.x); + CYBOZU_TEST_EQUAL(Q.y, -P.y); + + R = P + Q; + CYBOZU_TEST_ASSERT(R.isZero()); + CYBOZU_TEST_ASSERT(R.isNormalized()); + CYBOZU_TEST_ASSERT(R.isValid()); + + R = P + O; + CYBOZU_TEST_EQUAL(R, P); + R = O + P; + CYBOZU_TEST_EQUAL(R, P); + } + + { + Ec::dbl(R, P); +#ifndef MCL_EC_USE_AFFINE + CYBOZU_TEST_ASSERT(!R.isNormalized()); +#endif + CYBOZU_TEST_ASSERT(R.isValid()); + Ec R2 = P + P; + CYBOZU_TEST_EQUAL(R, R2); + { + Ec P2 = P; + Ec::dbl(P2, P2); + CYBOZU_TEST_EQUAL(P2, R2); + } + Ec R3L = R2 + P; + Ec R3R = P + R2; + CYBOZU_TEST_EQUAL(R3L, R3R); + { + Ec RR = R2; + RR = RR + P; + CYBOZU_TEST_EQUAL(RR, R3L); + RR = R2; + RR = P + RR; + CYBOZU_TEST_EQUAL(RR, R3L); + RR = P; + RR = RR + RR; + CYBOZU_TEST_EQUAL(RR, R2); + } + Ec::mul(R, P, 2); + CYBOZU_TEST_EQUAL(R, R2); + Ec R4L = R3L + R2; + Ec R4R = R2 + R3L; + CYBOZU_TEST_EQUAL(R4L, R4R); + Ec::mul(R, P, 5); + CYBOZU_TEST_EQUAL(R, R4L); + } + { + R = P; + for (int i = 0; i < 10; i++) { + R += P; + } + Ec R2; + Ec::mul(R2, P, 11); + CYBOZU_TEST_EQUAL(R, R2); + } + Ec::mul(R, P, n - 1); + CYBOZU_TEST_EQUAL(R, -P); + R += P; // Ec::mul(R, P, n); + CYBOZU_TEST_ASSERT(R.isZero()); + { + const int tbl[] = { 1, 2, 63, 64, 65, 127, 128, 129 }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + pow2test(P, tbl[i]); + } + } + { + Ec::mul(Q, P, 0); + CYBOZU_TEST_ASSERT(Q.isZero()); + Q = P; + CYBOZU_TEST_ASSERT(!Q.isZero()); + Ec::mul(Q, Q, 0); + CYBOZU_TEST_ASSERT(Q.isZero()); + Ec::mul(Q, P, 1); + CYBOZU_TEST_EQUAL(P, Q); + } + { + Ec R2; + P += P; + Q += P; + CYBOZU_TEST_ASSERT(!P.z.isOne()); + CYBOZU_TEST_ASSERT(!Q.z.isOne()); + Ec::add(R2, P, Q); + + P.normalize(); + CYBOZU_TEST_ASSERT(P.z.isOne()); + CYBOZU_TEST_ASSERT(!Q.z.isOne()); + // affine + generic + Ec::add(R, P, Q); + CYBOZU_TEST_EQUAL(R, R2); + // generic + affine + Ec::add(R, Q, P); + CYBOZU_TEST_EQUAL(R, R2); + + Q.normalize(); + CYBOZU_TEST_ASSERT(P.z.isOne()); + CYBOZU_TEST_ASSERT(Q.z.isOne()); + // affine + affine + Ec::add(R, P, Q); + CYBOZU_TEST_EQUAL(R, R2); + + P += P; + CYBOZU_TEST_ASSERT(!P.z.isOne()); + // generic + Ec::dbl(R2, P); + + P.normalize(); + CYBOZU_TEST_ASSERT(P.z.isOne()); + // affine + Ec::dbl(R, P); + CYBOZU_TEST_EQUAL(R, R2); + } + } + + void mul() const + { + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y); + Ec Q; + Ec R; + R.clear(); + for (int i = 0; i < 100; i++) { + Ec::mul(Q, P, i); + CYBOZU_TEST_EQUAL(Q, R); + R += P; + } + } + + void neg_mul() const + { + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y); + Ec Q; + Ec R; + R.clear(); + for (int i = 0; i < 100; i++) { + Ec::mul(Q, P, -i); + CYBOZU_TEST_EQUAL(Q, R); + R -= P; + } + } + void squareRoot() const + { + Fp x(para.gx); + Fp y(para.gy); + bool odd = y.isOdd(); + Fp yy; + bool b = Ec::getYfromX(yy, x, odd); + CYBOZU_TEST_ASSERT(b); + CYBOZU_TEST_EQUAL(yy, y); + Fp::neg(y, y); + odd = y.isOdd(); + yy.clear(); + b = Ec::getYfromX(yy, x, odd); + CYBOZU_TEST_ASSERT(b); + CYBOZU_TEST_EQUAL(yy, y); + } + void mul_fp() const + { + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y); + Ec Q; + Ec R; + R.clear(); + for (int i = 0; i < 100; i++) { + Ec::mul(Q, P, Zn(i)); + CYBOZU_TEST_EQUAL(Q, R); + R += P; + } + } + void str() const + { + const Fp x(para.gx); + const Fp y(para.gy); + Ec P(x, y); + Ec Q; + // not compressed + Ec::setCompressedExpression(false); + { + std::stringstream ss; + ss << P; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + { + Q.clear(); + CYBOZU_TEST_EQUAL(Q.getStr(), "0"); + } + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + int base = i == 0 ? 10 : 16; + bool withPrefix = j == 0; + int ioMode = base | (withPrefix ? mcl::IoPrefix : 0); + std::string expected = "1 " + x.getStr(ioMode) + " " + y.getStr(ioMode); + CYBOZU_TEST_EQUAL(P.getStr(ioMode), expected); + std::ostringstream os; + if (base == 16) { + os << std::hex; + } + if (withPrefix) { + os << std::showbase; + } + os << P; + CYBOZU_TEST_EQUAL(os.str(), expected); + } + } + { + P = -P; + std::stringstream ss; + ss << P; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + P.clear(); + { + std::stringstream ss; + ss << P; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + CYBOZU_TEST_EXCEPTION(P.setStr("1 3 5"), cybozu::Exception); + // compressed + Ec::setCompressedExpression(true); + P.set(x, y); + { + std::stringstream ss; + ss << P; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + { + P = -P; + std::stringstream ss; + ss << P; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + P.clear(); + { + std::stringstream ss; + ss << P; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + // IoSerialize, IoSerializeHexStr + const size_t adj = Ec::isMSBserialize() ? 0 : 1; + P.set(x, y); + { + std::string s = P.getStr(mcl::IoSerialize); + CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize() + adj); + Q.setStr(s, mcl::IoSerialize); + CYBOZU_TEST_EQUAL(P, Q); + } + { + std::string s = P.getStr(mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(s.size(), (Fp::getByteSize() + adj) * 2); + Q.setStr(s, mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(P, Q); + } + P = -P; + { + std::string s = P.getStr(mcl::IoSerialize); + CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize() + adj); + Q.setStr(s, mcl::IoSerialize); + CYBOZU_TEST_EQUAL(P, Q); + } + { + std::string s = P.getStr(mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(s.size(), (Fp::getByteSize() + adj) * 2); + Q.setStr(s, mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(P, Q); + } + P.clear(); + { + std::string s = P.getStr(mcl::IoSerialize); + CYBOZU_TEST_EQUAL(s.size(), Fp::getByteSize() + adj); + CYBOZU_TEST_ASSERT(mcl::fp::isZeroArray(s.c_str(), s.size())); + Q.setStr(s, mcl::IoSerialize); + CYBOZU_TEST_EQUAL(P, Q); + } + { + std::string s = P.getStr(mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(s.size(), (Fp::getByteSize() + adj) * 2); + for (size_t i = 0; i < s.size(); i++) { + CYBOZU_TEST_EQUAL(s[i], '0'); + } + Q.setStr(s, mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(P, Q); + } + } + void ioMode() const + { + const Fp x(para.gx); + const Fp y(para.gy); + Ec P(x, y); + const mcl::IoMode tbl[] = { + mcl::IoBin, + mcl::IoDec, + mcl::IoHex, + mcl::IoArray, + mcl::IoArrayRaw, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Fp::setIoMode(tbl[i]); + { + std::stringstream ss; + ss << P; + Ec Q; + ss >> Q; + CYBOZU_TEST_EQUAL(P, Q); + } + { + std::stringstream ss; + Ec Q; + Q.clear(); + ss << Q; + Ec R; + ss >> R; + CYBOZU_TEST_EQUAL(Q, R); + } + } + Fp::setIoMode(mcl::IoAuto); + } + void mulCT() const + { + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y), Q1, Q2; + for (int i = 0; i < 100; i++) { + Zn r = i; + Ec::mul(Q1, P, r); + Ec::mulCT(Q2, P, r); + CYBOZU_TEST_EQUAL(Q1, Q2); + } + } + void compare() const + { + Fp x(para.gx); + Fp y(para.gy); + Ec P1(x, y); + Ec P2(x, -y); + int c = Ec::compare(P1, P2); + int cx = Fp::compare(y, -y); + CYBOZU_TEST_EQUAL(c, cx); + c = Ec::compare(P2, P1); + cx = Fp::compare(-y, y); + CYBOZU_TEST_EQUAL(c, cx); + CYBOZU_TEST_EQUAL(Ec::compare(P1, P1), 0); + bool b1, b2; + b1 = P1 <= P2; + b2 = y <= -y; + CYBOZU_TEST_EQUAL(b1, b2); + b1 = P1 < P2; + b2 = y < -y; + CYBOZU_TEST_EQUAL(b1, b2); + CYBOZU_TEST_ASSERT(!(P1 < P1)); + CYBOZU_TEST_ASSERT((P1 <= P1)); + } + + template<class F> + void test(F f, const char *msg) const + { + const int N = 300000; + Fp x(para.gx); + Fp y(para.gy); + Ec P(x, y); + Ec Q = P + P + P; + clock_t begin = clock(); + for (int i = 0; i < N; i++) { + f(Q, P, Q); + } + clock_t end = clock(); + printf("%s %.2fusec\n", msg, (end - begin) / double(CLOCKS_PER_SEC) / N * 1e6); + } +/* +Affine : sandy-bridge +add 3.17usec +sub 2.43usec +dbl 3.32usec +mul 905.00usec +Jacobi +add 2.34usec +sub 2.65usec +dbl 1.56usec +mul 499.00usec +*/ + void run() const + { + cstr(); + ope(); + mul(); + neg_mul(); + mul_fp(); + squareRoot(); + str(); + ioMode(); + mulCT(); + compare(); + } +private: + Test(const Test&); + void operator=(const Test&); +}; + +void test_sub_sub(const mcl::EcParam& para, mcl::fp::Mode fpMode) +{ + puts("Proj"); + Test(para, fpMode, mcl::ec::Proj).run(); + puts("Jacobi"); + Test(para, fpMode, mcl::ec::Jacobi).run(); +} + +void test_sub(const mcl::EcParam *para, size_t paraNum) +{ + for (size_t i = 0; i < paraNum; i++) { + puts(para[i].name); + test_sub_sub(para[i], mcl::fp::FP_GMP); +#ifdef MCL_USE_LLVM + test_sub_sub(para[i], mcl::fp::FP_LLVM); + test_sub_sub(para[i], mcl::fp::FP_LLVM_MONT); +#endif +#ifdef MCL_USE_XBYAK + test_sub_sub(para[i], mcl::fp::FP_XBYAK); +#endif + } +} + +int g_partial = -1; + +CYBOZU_TEST_AUTO(all) +{ + if (g_partial & (1 << 3)) { + const struct mcl::EcParam para3[] = { + // mcl::ecparam::p160_1, + mcl::ecparam::secp160k1, + mcl::ecparam::secp192k1, + mcl::ecparam::NIST_P192, + }; + test_sub(para3, CYBOZU_NUM_OF_ARRAY(para3)); + } + + if (g_partial & (1 << 4)) { + const struct mcl::EcParam para4[] = { + mcl::ecparam::secp224k1, + mcl::ecparam::secp256k1, + mcl::ecparam::NIST_P224, + mcl::ecparam::NIST_P256, + }; + test_sub(para4, CYBOZU_NUM_OF_ARRAY(para4)); + } + +#if MCL_MAX_BIT_SIZE >= 384 + if (g_partial & (1 << 6)) { + const struct mcl::EcParam para6[] = { + // mcl::ecparam::secp384r1, + mcl::ecparam::NIST_P384, + }; + test_sub(para6, CYBOZU_NUM_OF_ARRAY(para6)); + } +#endif + +#if MCL_MAX_BIT_SIZE >= 521 + if (g_partial & (1 << 9)) { + const struct mcl::EcParam para9[] = { + // mcl::ecparam::secp521r1, + mcl::ecparam::NIST_P521, + }; + test_sub(para9, CYBOZU_NUM_OF_ARRAY(para9)); + } +#endif +} + +int main(int argc, char *argv[]) +{ + if (argc == 1) { + g_partial = -1; + } else { + g_partial = 0; + for (int i = 1; i < argc; i++) { + g_partial |= 1 << atoi(argv[i]); + } + } + return cybozu::test::autoRun.run(argc, argv); +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/ecdsa_c_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/ecdsa_c_test.cpp new file mode 100644 index 000000000..e0af38182 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/ecdsa_c_test.cpp @@ -0,0 +1,51 @@ +#include <mcl/ecdsa.h> +#include <cybozu/test.hpp> +#include <string.h> + +template<class T, class Serializer, class Deserializer> +void serializeTest(const T& x, const Serializer& serialize, const Deserializer& deserialize) +{ + char buf[128]; + size_t n = serialize(buf, sizeof(buf), &x); + CYBOZU_TEST_ASSERT(n > 0); + T y; + size_t m = deserialize(&y, buf, n); + CYBOZU_TEST_EQUAL(m, n); + CYBOZU_TEST_ASSERT(memcmp(&x, &y, n) == 0); +} + +CYBOZU_TEST_AUTO(ecdsa) +{ + int ret; + ret = ecdsaInit(); + CYBOZU_TEST_EQUAL(ret, 0); + ecdsaSecretKey sec; + ecdsaPublicKey pub; + ecdsaPrecomputedPublicKey *ppub; + ecdsaSignature sig; + const char *msg = "hello"; + mclSize msgSize = strlen(msg); + + ret = ecdsaSecretKeySetByCSPRNG(&sec); + CYBOZU_TEST_EQUAL(ret, 0); + serializeTest(sec, ecdsaSecretKeySerialize, ecdsaSecretKeyDeserialize); + + ecdsaGetPublicKey(&pub, &sec); + serializeTest(pub, ecdsaPublicKeySerialize, ecdsaPublicKeyDeserialize); + ecdsaSign(&sig, &sec, msg, msgSize); + serializeTest(sig, ecdsaSignatureSerialize, ecdsaSignatureDeserialize); + CYBOZU_TEST_ASSERT(ecdsaVerify(&sig, &pub, msg, msgSize)); + + ppub = ecdsaPrecomputedPublicKeyCreate(); + CYBOZU_TEST_ASSERT(ppub); + ret = ecdsaPrecomputedPublicKeyInit(ppub, &pub); + CYBOZU_TEST_EQUAL(ret, 0); + + CYBOZU_TEST_ASSERT(ecdsaVerifyPrecomputed(&sig, ppub, msg, msgSize)); + + sig.d[0]++; + CYBOZU_TEST_ASSERT(!ecdsaVerify(&sig, &pub, msg, msgSize)); + CYBOZU_TEST_ASSERT(!ecdsaVerifyPrecomputed(&sig, ppub, msg, msgSize)); + + ecdsaPrecomputedPublicKeyDestroy(ppub); +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/ecdsa_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/ecdsa_test.cpp new file mode 100644 index 000000000..332c9ee27 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/ecdsa_test.cpp @@ -0,0 +1,69 @@ +#define PUT(x) std::cout << #x "=" << x << std::endl; +#include <stdlib.h> +#include <stdio.h> +void put(const void *buf, size_t bufSize) +{ + const unsigned char* p = (const unsigned char*)buf; + for (size_t i = 0; i < bufSize; i++) { + printf("%02x", p[i]); + } + printf("\n"); +} +#include <mcl/ecdsa.hpp> +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> + +using namespace mcl::ecdsa; + +CYBOZU_TEST_AUTO(ecdsa) +{ + init(); + SecretKey sec; + PublicKey pub; + sec.setByCSPRNG(); + getPublicKey(pub, sec); + Signature sig; + const std::string msg = "hello"; + sign(sig, sec, msg.c_str(), msg.size()); + CYBOZU_TEST_ASSERT(verify(sig, pub, msg.c_str(), msg.size())); + sig.s += 1; + CYBOZU_TEST_ASSERT(!verify(sig, pub, msg.c_str(), msg.size())); +} + +CYBOZU_TEST_AUTO(value) +{ + const std::string msg = "hello"; + const char *secStr = "83ecb3984a4f9ff03e84d5f9c0d7f888a81833643047acc58eb6431e01d9bac8"; + const char *pubxStr = "653bd02ba1367e5d4cd695b6f857d1cd90d4d8d42bc155d85377b7d2d0ed2e71"; + const char *pubyStr = "04e8f5da403ab78decec1f19e2396739ea544e2b14159beb5091b30b418b813a"; + const char *sigStr = "a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5de5d79a2ba44e311d04fdca263639283965780bce9169822be9cc81756e95a24"; + + SecretKey sec; + sec.setStr(secStr, 16); + CYBOZU_TEST_EQUAL(sec.getStr(16), secStr); + PublicKey pub; + getPublicKey(pub, sec); + pub.normalize(); + Ec t(Fp(pubxStr, 16), Fp(pubyStr, 16)); + CYBOZU_TEST_EQUAL(pub, t); + Signature sig; + sig.r.setStr(std::string(sigStr, 64), 16); + sig.s.setStr(std::string(sigStr + 64, 64), 16); + PUT(sig); + CYBOZU_TEST_ASSERT(verify(sig, pub, msg.c_str(), msg.size())); +} + +CYBOZU_TEST_AUTO(bench) +{ + const std::string msg = "hello"; + SecretKey sec; + PublicKey pub; + PrecomputedPublicKey ppub; + sec.setByCSPRNG(); + getPublicKey(pub, sec); + ppub.init(pub); + Signature sig; + CYBOZU_BENCH_C("sign", 1000, sign, sig, sec, msg.c_str(), msg.size()); + CYBOZU_BENCH_C("pub.verify ", 1000, verify, sig, pub, msg.c_str(), msg.size()); + CYBOZU_BENCH_C("ppub.verify", 1000, verify, sig, ppub, msg.c_str(), msg.size()); +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/elgamal_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/elgamal_test.cpp new file mode 100644 index 000000000..9532fc597 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/elgamal_test.cpp @@ -0,0 +1,155 @@ +#include <cybozu/test.hpp> +#include <cybozu/random_generator.hpp> +#include <mcl/fp.hpp> +#include <mcl/ecparam.hpp> +#include <mcl/elgamal.hpp> + +struct TagZn; +typedef mcl::FpT<> Fp; +typedef mcl::FpT<TagZn> Zn; +typedef mcl::EcT<Fp> Ec; +typedef mcl::ElgamalT<Ec, Zn> ElgamalEc; + +const mcl::EcParam& para = mcl::ecparam::secp192k1; +cybozu::RandomGenerator rg; + +CYBOZU_TEST_AUTO(testEc) +{ + Fp::init(para.p); + Zn::init(para.n); + Ec::init(para.a, para.b); + const Fp x0(para.gx); + const Fp y0(para.gy); + const size_t bitSize = Zn::getBitSize(); + const Ec P(x0, y0); + /* + Zn = <P> + */ + ElgamalEc::PrivateKey prv; + prv.init(P, bitSize, rg); + prv.setCache(0, 60000); + const ElgamalEc::PublicKey& pub = prv.getPublicKey(); + + const int m1 = 12345; + const int m2 = 17655; + ElgamalEc::CipherText c1, c2; + pub.enc(c1, m1, rg); + pub.enc(c2, m2, rg); + Zn dec1, dec2; + prv.dec(dec1, c1); + prv.dec(dec2, c2); + // dec(enc) = id + CYBOZU_TEST_EQUAL(dec1, m1); + CYBOZU_TEST_EQUAL(dec2, m2); + CYBOZU_TEST_EQUAL(prv.dec(c1), m1); + CYBOZU_TEST_EQUAL(prv.dec(c2), m2); + // iostream + { + ElgamalEc::PublicKey pub2; + ElgamalEc::PrivateKey prv2; + ElgamalEc::CipherText cc1, cc2; + { + std::stringstream ss; + ss << prv; + ss >> prv2; + } + Zn d; + prv2.dec(d, c1); + CYBOZU_TEST_EQUAL(d, m1); + { + std::stringstream ss; + ss << c1; + ss >> cc1; + } + d = 0; + prv2.dec(d, cc1); + CYBOZU_TEST_EQUAL(d, m1); + { + std::stringstream ss; + ss << pub; + ss >> pub2; + } + pub2.enc(cc2, m2, rg); + prv.dec(d, cc2); + CYBOZU_TEST_EQUAL(d, m2); + } + // enc(m1) enc(m2) = enc(m1 + m2) + c1.add(c2); + prv.dec(dec1, c1); + CYBOZU_TEST_EQUAL(dec1, m1 + m2); + // enc(m1) x = enc(m1 + x) + { + const int x = 555; + pub.add(c1, x); + prv.dec(dec1, c1); + CYBOZU_TEST_EQUAL(dec1, m1 + m2 + x); + } + // rerandomize + c1 = c2; + pub.rerandomize(c1, rg); + // verify c1 != c2 + CYBOZU_TEST_ASSERT(c1.c1 != c2.c1); + CYBOZU_TEST_ASSERT(c1.c2 != c2.c2); + prv.dec(dec1, c1); + // dec(c1) = dec(c2) + CYBOZU_TEST_EQUAL(dec1, m2); + + // check neg + { + ElgamalEc::CipherText c; + Zn m = 1234; + pub.enc(c, m, rg); + c.neg(); + Zn dec; + prv.dec(dec, c); + CYBOZU_TEST_EQUAL(dec, -m); + } + // check mul + { + ElgamalEc::CipherText c; + Zn m = 123; + int x = 111; + pub.enc(c, m, rg); + Zn dec; + prv.dec(dec, c); + c.mul(x); + prv.dec(dec, c); + m *= x; + CYBOZU_TEST_EQUAL(dec, m); + } + + // check negative value + for (int i = -10; i < 10; i++) { + ElgamalEc::CipherText c; + const Zn mm = i; + pub.enc(c, mm, rg); + Zn dec; + prv.dec(dec, c, 1000); + CYBOZU_TEST_EQUAL(dec, mm); + } + + // isZeroMessage + for (int m = 0; m < 10; m++) { + ElgamalEc::CipherText c0; + pub.enc(c0, m, rg); + if (m == 0) { + CYBOZU_TEST_ASSERT(prv.isZeroMessage(c0)); + } else { + CYBOZU_TEST_ASSERT(!prv.isZeroMessage(c0)); + } + } + // zkp + { + ElgamalEc::Zkp zkp; + ElgamalEc::CipherText c; + pub.encWithZkp(c, zkp, 0, rg); + CYBOZU_TEST_ASSERT(pub.verify(c, zkp)); + zkp.s0 += 1; + CYBOZU_TEST_ASSERT(!pub.verify(c, zkp)); + pub.encWithZkp(c, zkp, 1, rg); + CYBOZU_TEST_ASSERT(pub.verify(c, zkp)); + zkp.s0 += 1; + CYBOZU_TEST_ASSERT(!pub.verify(c, zkp)); + CYBOZU_TEST_EXCEPTION_MESSAGE(pub.encWithZkp(c, zkp, 2, rg), cybozu::Exception, "encWithZkp"); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/fp_generator_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/fp_generator_test.cpp new file mode 100644 index 000000000..60ec5cd41 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/fp_generator_test.cpp @@ -0,0 +1,207 @@ +#include <cybozu/test.hpp> +#if MCL_SIZEOF_UNIT == 4 +// not support +#else +#include <mcl/gmp_util.hpp> +#include <stdint.h> +#include <string> +#include <cybozu/itoa.hpp> +#include <mcl/fp.hpp> +#include "../src/fp_generator.hpp" +#include <iostream> +#include <cybozu/xorshift.hpp> +#include <cybozu/benchmark.hpp> + +typedef mcl::FpT<> Fp; + +const int MAX_N = 4; + +const char *primeTable[] = { + "0x7fffffffffffffffffffffffffffffff", // 127bit(not full) + "0xffffffffffffffffffffffffffffff61", // 128bit(full) + "0xfffffffffffffffffffffffffffffffffffffffeffffee37", // 192bit(full) + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", // 254bit(not full) +}; + +void strToArray(uint64_t *p, size_t n, const char *pStr) +{ + mpz_class x; + mcl::gmp::setStr(x, pStr, 16); + mcl::gmp::getArray(p, n, x); +} + +struct Int { + int vn; + uint64_t v[MAX_N]; + Int() + : vn(0) + { + } + explicit Int(int vn) + { + if (vn > MAX_N) { + printf("vn(%d) is too large\n", vn); + exit(1); + } + this->vn = vn; + } + void set(const char *str) { setStr(str); } + void set(const Fp& rhs) + { + mcl::gmp::getArray(v, MAX_N, rhs.getMpz()); + } + void set(const uint64_t* x) + { + for (int i = 0; i < vn; i++) v[i] = x[i]; + } + void setStr(const char *str) + { + strToArray(v, MAX_N, str); + } + std::string getStr() const + { + std::string ret; + for (int i = 0; i < vn; i++) { + ret += cybozu::itohex(v[vn - 1 - i], false); + } + return ret; + } + void put(const char *msg = "") const + { + if (msg) printf("%s=", msg); + printf("%s\n", getStr().c_str()); + } + bool operator==(const Int& rhs) const + { + if (vn != rhs.vn) return false; + for (int i = 0; i < vn; i++) { + if (v[i] != rhs.v[i]) return false; + } + return true; + } + bool operator!=(const Int& rhs) const { return !operator==(rhs); } + bool operator==(const Fp& rhs) const + { + Int t(vn); + t.set(rhs); + return operator==(t); + } + bool operator!=(const Fp& rhs) const { return !operator==(rhs); } +}; +static inline std::ostream& operator<<(std::ostream& os, const Int& x) +{ + return os << x.getStr(); +} + +void testAddSub(const mcl::fp::Op& op) +{ + Fp x, y; + const uint64_t *p = op.p; + Int mx(op.N), my(op.N); + x.setStr("0x8811aabb23427cc"); + y.setStr("0x8811aabb23427cc11"); + mx.set(x); + my.set(y); + for (int i = 0; i < 30; i++) { + CYBOZU_TEST_EQUAL(mx, x); + x += x; + op.fp_add(mx.v, mx.v, mx.v, p); + } + for (int i = 0; i < 30; i++) { + CYBOZU_TEST_EQUAL(mx, x); + x += y; + op.fp_add(mx.v, mx.v, my.v, p); + } + for (int i = 0; i < 30; i++) { + CYBOZU_TEST_EQUAL(my, y); + y -= x; + op.fp_sub(my.v, my.v, mx.v, p); + } +} + +void testNeg(const mcl::fp::Op& op) +{ + Fp x; + Int mx(op.N), my(op.N); + const char *tbl[] = { + "0", + "0x12346", + "0x11223344556677881122334455667788", + "0x0abbccddeeffaabb0000000000000000", + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + x.setStr(tbl[i]); + mx.set(x); + x = -x; + op.fp_neg(mx.v, mx.v, op.p); + CYBOZU_TEST_EQUAL(mx, x); + } +} + +#if 0 +void testMulI(const mcl::fp::FpGenerator& fg, int pn) +{ + cybozu::XorShift rg; +//printf("pn=%d, %p\n", pn, fg.mulUnit_); + for (int i = 0; i < 100; i++) { + uint64_t x[MAX_N]; + uint64_t z[MAX_N + 1]; + rg.read(x, pn); + uint64_t y = rg.get64(); + mpz_class mx; + mcl::gmp::setArray(mx, x, pn); + mpz_class my; + mcl::gmp::set(my, y); + mx *= my; + uint64_t d = fg.mulUnit_(z, x, y); + z[pn] = d; + mcl::gmp::setArray(my, z, pn + 1); + CYBOZU_TEST_EQUAL(mx, my); + } + { + uint64_t x[MAX_N]; + uint64_t z[MAX_N + 1]; + rg.read(x, pn); + uint64_t y = rg.get64(); + CYBOZU_BENCH_C("mulUnit", 10000000, fg.mulUnit_, z, x, y); + } +} +#endif + +void testShr1(const mcl::fp::Op& op, int pn) +{ + cybozu::XorShift rg; + for (int i = 0; i < 100; i++) { + uint64_t x[MAX_N]; + uint64_t z[MAX_N]; + rg.read(x, pn); + mpz_class mx; + mcl::gmp::setArray(mx, x, pn); + mx >>= 1; + op.fp_shr1(z, x); + mpz_class my; + mcl::gmp::setArray(my, z, pn); + CYBOZU_TEST_EQUAL(mx, my); + } +} + +void test(const char *pStr) +{ + printf("test %s\n", pStr); + Fp::init(pStr, mcl::fp::FP_XBYAK); + const mcl::fp::Op& op = Fp::getOp(); + const int pn = (int)op.N; + testAddSub(op); + testNeg(op); +// testMulI(*op.fg, pn); + testShr1(op, pn); +} + +CYBOZU_TEST_AUTO(all) +{ + if (!mcl::fp::isEnableJIT()) return; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(primeTable); i++) { + test(primeTable[i]); + } +} +#endif diff --git a/vendor/github.com/dexon-foundation/mcl/test/fp_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/fp_test.cpp new file mode 100644 index 000000000..dc1b01ef4 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/fp_test.cpp @@ -0,0 +1,1046 @@ +#define PUT(x) std::cout << #x "=" << (x) << std::endl +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/test.hpp> +#include <mcl/fp.hpp> +#include "../src/low_func.hpp" +#include "../src/proto.hpp" +#include <time.h> +#include <cybozu/benchmark.hpp> +#include <cybozu/option.hpp> +#include <cybozu/sha2.hpp> + +#ifdef _MSC_VER + #pragma warning(disable: 4127) // const condition +#endif + +typedef mcl::FpT<> Fp; + +CYBOZU_TEST_AUTO(sizeof) +{ + CYBOZU_TEST_EQUAL(sizeof(Fp), sizeof(mcl::fp::Unit) * Fp::maxSize); +} + +void cstrTest() +{ + const struct { + const char *str; + int val; + } tbl[] = { + { "0", 0 }, + { "1", 1 }, + { "123", 123 }, + { "0x123", 0x123 }, + { "0b10101", 21 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + // string cstr + Fp x(tbl[i].str); + CYBOZU_TEST_EQUAL(x, tbl[i].val); + + // int cstr + Fp y(tbl[i].val); + CYBOZU_TEST_EQUAL(y, x); + + // copy cstr + Fp z(x); + CYBOZU_TEST_EQUAL(z, x); + + // assign int + Fp w; + w = tbl[i].val; + CYBOZU_TEST_EQUAL(w, x); + + // assign self + Fp u; + u = w; + CYBOZU_TEST_EQUAL(u, x); + + // conv + std::ostringstream os; + os << tbl[i].val; + + std::string str; + x.getStr(str); + CYBOZU_TEST_EQUAL(str, os.str()); + } + const struct { + const char *str; + int val; + } tbl2[] = { + { "-123", 123 }, + { "-0x123", 0x123 }, + { "-0b10101", 21 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl2); i++) { + Fp x(tbl2[i].str); + x = -x; + CYBOZU_TEST_EQUAL(x, tbl2[i].val); + } +} + +void setStrTest() +{ + const struct { + const char *in; + int out; + int base; + } tbl[] = { + { "100", 100, 0 }, // set base = 10 if base = 0 + { "100", 4, 2 }, + { "100", 256, 16 }, + { "0b100", 4, 0 }, + { "0b100", 4, 2 }, + { "0x100", 256, 0 }, + { "0x100", 256, 16 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Fp x; + x.setStr(tbl[i].in, tbl[i].base); + CYBOZU_TEST_EQUAL(x, tbl[i].out); + } + // use prefix if base conflicts with prefix + { + Fp x; + CYBOZU_TEST_EXCEPTION(x.setStr("0b100", 16), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(x.setStr("0b100", 10), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(x.setStr("0x100", 2), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(x.setStr("0x100", 10), cybozu::Exception); + } +} + +void streamTest() +{ + const struct { + const char *in; + int out10; + int out16; + } tbl[] = { + { "100", 100, 256 }, // set base = 10 if base = 0 + { "0x100", 256, 256 }, + }; + Fp::setIoMode(0); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + { + std::istringstream is(tbl[i].in); + Fp x; + is >> x; + CYBOZU_TEST_EQUAL(x, tbl[i].out10); + } + { + std::istringstream is(tbl[i].in); + Fp x; + is >> std::hex >> x; + CYBOZU_TEST_EQUAL(x, tbl[i].out16); + } + } + // use prefix if base conflicts with prefix + std::istringstream is("0b100"); + Fp x; + CYBOZU_TEST_EXCEPTION(is >> std::hex >> x, cybozu::Exception); + { + std::ostringstream os; + os << Fp(123); + CYBOZU_TEST_EQUAL(os.str(), "123"); + } + { + std::ostringstream os; + os << std::hex << Fp(0x123); + CYBOZU_TEST_EQUAL(os.str(), "123"); + } + { + std::ostringstream os; + os << std::hex << std::showbase << Fp(0x123); + CYBOZU_TEST_EQUAL(os.str(), "0x123"); + } +} + +void ioModeTest() +{ + Fp x(123); + const struct { + mcl::IoMode ioMode; + std::string expected; + } tbl[] = { + { mcl::IoBin, "1111011" }, + { mcl::IoDec, "123" }, + { mcl::IoHex, "7b" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Fp::setIoMode(tbl[i].ioMode); + for (int j = 0; j < 2; j++) { + std::stringstream ss; + if (j == 1) { + ss << std::hex; + } + ss << x; + CYBOZU_TEST_EQUAL(ss.str(), tbl[i].expected); + Fp y; + y.clear(); + ss >> y; + CYBOZU_TEST_EQUAL(x, y); + } + } + for (int i = 0; i < 2; i++) { + if (i == 0) { + Fp::setIoMode(mcl::IoArray); + } else { + Fp::setIoMode(mcl::IoArrayRaw); + } + std::stringstream ss; + ss << x; + CYBOZU_TEST_EQUAL(ss.str().size(), Fp::getByteSize()); + Fp y; + ss >> y; + CYBOZU_TEST_EQUAL(x, y); + } + Fp::setIoMode(mcl::IoAuto); +} + +void edgeTest() +{ + const mpz_class& m = Fp::getOp().mp; + /* + real mont + 0 0 + 1 R^-1 + R 1 + -1 -R^-1 + -R -1 + */ + mpz_class t = 1; + const size_t N = Fp::getUnitSize(); + const mpz_class R = (t << (N * mcl::fp::UnitBitSize)) % m; + const mpz_class tbl[] = { + 0, 1, R, m - 1, m - R + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const mpz_class& x = tbl[i]; + for (size_t j = i; j < CYBOZU_NUM_OF_ARRAY(tbl); j++) { + const mpz_class& y = tbl[j]; + mpz_class z = (x * y) % m; + Fp xx, yy; + xx.setMpz(x); + yy.setMpz(y); + Fp zz = xx * yy; + zz.getMpz(t); + CYBOZU_TEST_EQUAL(z, t); + } + } + t = m; + t /= 2; + Fp x; + x.setMpz(t); + CYBOZU_TEST_EQUAL(x * 2, -1); + t += 1; + x.setMpz(t); + CYBOZU_TEST_EQUAL(x * 2, 1); +} + +void convTest() +{ +#if 1 + const char *bin, *hex, *dec; + if (Fp::getBitSize() <= 117) { + bin = "0b1000000000000000000000000000000000000000000000000000000000001110"; + hex = "0x800000000000000e"; + dec = "9223372036854775822"; + } else { + bin = "0b100100011010001010110011110001001000000010010001101000101011001111000100100000001001000110100010101100111100010010000"; + hex = "0x123456789012345678901234567890"; + dec = "94522879687365475552814062743484560"; + } +#else + const char *bin = "0b1001000110100"; + const char *hex = "0x1234"; + const char *dec = "4660"; +#endif + Fp b(bin); + Fp h(hex); + Fp d(dec); + CYBOZU_TEST_EQUAL(b, h); + CYBOZU_TEST_EQUAL(b, d); + + std::string str; + b.getStr(str, mcl::IoBinPrefix); + CYBOZU_TEST_EQUAL(str, bin); + b.getStr(str); + CYBOZU_TEST_EQUAL(str, dec); + b.getStr(str, mcl::IoHexPrefix); + CYBOZU_TEST_EQUAL(str, hex); +} + +void compareTest() +{ + { + const struct { + int lhs; + int rhs; + int cmp; + } tbl[] = { + { 0, 0, 0 }, + { 1, 0, 1 }, + { 0, 1, -1 }, + { -1, 0, 1 }, // m-1, 0 + { 0, -1, -1 }, // 0, m-1 + { 123, 456, -1 }, + { 456, 123, 1 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const Fp x(tbl[i].lhs); + const Fp y(tbl[i].rhs); + const int cmp = tbl[i].cmp; + if (cmp == 0) { + CYBOZU_TEST_EQUAL(x, y); + CYBOZU_TEST_ASSERT(x >= y); + CYBOZU_TEST_ASSERT(x <= y); + } else if (cmp > 0) { + CYBOZU_TEST_ASSERT(x > y); + CYBOZU_TEST_ASSERT(x >= y); + } else { + CYBOZU_TEST_ASSERT(x < y); + CYBOZU_TEST_ASSERT(x <= y); + } + } + } + { + Fp x(5); + CYBOZU_TEST_ASSERT(x < 10); + CYBOZU_TEST_ASSERT(x == 5); + CYBOZU_TEST_ASSERT(x > 2); + } + { + Fp x(1); + CYBOZU_TEST_ASSERT(x.isOne()); + x = 2; + CYBOZU_TEST_ASSERT(!x.isOne()); + } + { + const struct { + int v; + bool expected; + } tbl[] = { + { 0, false }, + { 1, false }, + { -1, true }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Fp x = tbl[i].v; + CYBOZU_TEST_EQUAL(x.isNegative(), tbl[i].expected); + } + std::string str; + Fp::getModulo(str); + char buf[1024]; + size_t n = Fp::getModulo(buf, sizeof(buf)); + CYBOZU_TEST_EQUAL(n, str.size()); + CYBOZU_TEST_EQUAL(buf, str.c_str()); + mpz_class half(str); + half = (half - 1) / 2; + Fp x; + x.setMpz(half - 1); + CYBOZU_TEST_ASSERT(!x.isNegative()); + x.setMpz(half); + CYBOZU_TEST_ASSERT(!x.isNegative()); + x.setMpz(half + 1); + CYBOZU_TEST_ASSERT(x.isNegative()); + } +} + +void moduloTest(const char *pStr) +{ + std::string str; + Fp::getModulo(str); + CYBOZU_TEST_EQUAL(str, mcl::gmp::getStr(mpz_class(pStr))); +} + +void opeTest() +{ + const struct { + int x; + int y; + int add; // x + y + int sub; // x - y + int mul; // x * y + int sqr; // x^2 + } tbl[] = { + { 0, 1, 1, -1, 0, 0 }, + { 9, 5, 14, 4, 45, 81 }, + { 10, 13, 23, -3, 130, 100 }, + { 2000, 1000, 3000, 1000, 2000 * 1000, 2000 * 2000 }, + { 12345, 9999, 12345 + 9999, 12345 - 9999, 12345 * 9999, 12345 * 12345 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const Fp x(tbl[i].x); + const Fp y(tbl[i].y); + Fp z; + Fp::add(z, x, y); + CYBOZU_TEST_EQUAL(z, tbl[i].add); + Fp::sub(z, x, y); + CYBOZU_TEST_EQUAL(z, tbl[i].sub); + Fp::mul(z, x, y); + CYBOZU_TEST_EQUAL(z, tbl[i].mul); + + Fp r; + Fp::inv(r, y); + Fp::mul(z, z, r); + CYBOZU_TEST_EQUAL(z, tbl[i].x); + z = x + y; + CYBOZU_TEST_EQUAL(z, tbl[i].add); + z = x - y; + CYBOZU_TEST_EQUAL(z, tbl[i].sub); + z = x * y; + CYBOZU_TEST_EQUAL(z, tbl[i].mul); + + Fp::sqr(z, x); + CYBOZU_TEST_EQUAL(z, tbl[i].sqr); + + z = x / y; + z *= y; + CYBOZU_TEST_EQUAL(z, tbl[i].x); + } + if (!Fp::isFullBit()) { + Fp x(5), y(3), z; + Fp::addPre(z, x, y); + if (Fp::compareRaw(z, Fp::getP()) >= 0) { + Fp::subPre(z, z, Fp::getP()); + } + CYBOZU_TEST_EQUAL(z, Fp(8)); + if (Fp::compareRaw(x, y) < 0) { + Fp::addPre(x, x, Fp::getP()); + } + Fp::subPre(x, x, y); + CYBOZU_TEST_EQUAL(x, Fp(2)); + } +} + +struct tag2; + +void powTest() +{ + Fp x, y, z; + x = 12345; + z = 1; + for (int i = 0; i < 100; i++) { + Fp::pow(y, x, i); + CYBOZU_TEST_EQUAL(y, z); + z *= x; + } + x = z; + Fp::pow(z, x, Fp::getOp().mp - 1); + CYBOZU_TEST_EQUAL(z, 1); + Fp::pow(z, x, Fp::getOp().mp); + CYBOZU_TEST_EQUAL(z, x); + typedef mcl::FpT<tag2, 128> Fp_other; + Fp_other::init("1009"); + x = 5; + Fp_other n = 3; + z = 3; + Fp::pow(x, x, z); + CYBOZU_TEST_EQUAL(x, 125); + x = 5; + Fp::pow(x, x, n); + CYBOZU_TEST_EQUAL(x, 125); +} + +void mulUnitTest() +{ + Fp x(-1), y, z; + for (unsigned int u = 0; u < 20; u++) { + Fp::mul(y, x, u); + Fp::mulUnit(z, x, u); + CYBOZU_TEST_EQUAL(y, z); + } +} + +void powNegTest() +{ + Fp x, y, z; + x = 12345; + z = 1; + Fp rx = 1 / x; + for (int i = 0; i < 100; i++) { + Fp::pow(y, x, -i); + CYBOZU_TEST_EQUAL(y, z); + z *= rx; + } +} + +void powFpTest() +{ + Fp x, y, z; + x = 12345; + z = 1; + for (int i = 0; i < 100; i++) { + Fp::pow(y, x, Fp(i)); + CYBOZU_TEST_EQUAL(y, z); + z *= x; + } +} + +void powGmp() +{ + Fp x, y, z; + x = 12345; + z = 1; + for (int i = 0; i < 100; i++) { + Fp::pow(y, x, mpz_class(i)); + CYBOZU_TEST_EQUAL(y, z); + z *= x; + } +} + +struct TagAnother; + +void anotherFpTest(mcl::fp::Mode mode) +{ + typedef mcl::FpT<TagAnother, 128> G; + G::init("13", mode); + G a = 3; + G b = 9; + a *= b; + CYBOZU_TEST_EQUAL(a, 1); +} + +void setArrayTest1() +{ + char b1[] = { 0x56, 0x34, 0x12 }; + Fp x; + x.setArray(b1, 3); + CYBOZU_TEST_EQUAL(x, 0x123456); + int b2[] = { 0x12, 0x34 }; + x.setArray(b2, 2); + CYBOZU_TEST_EQUAL(x, Fp("0x3400000012")); +} + +void setArrayTest2(mcl::fp::Mode mode) +{ + Fp::init("0x10000000000001234567a5", mode); + const struct { + uint32_t buf[3]; + size_t bufN; + const char *expected; + } tbl[] = { + { { 0x234567a4, 0x00000001, 0x00100000}, 1, "0x234567a4" }, + { { 0x234567a4, 0x00000001, 0x00100000}, 2, "0x1234567a4" }, + { { 0x234567a4, 0x00000001, 0x00080000}, 3, "0x08000000000001234567a4" }, + { { 0x234567a4, 0x00000001, 0x00100000}, 3, "0x10000000000001234567a4" }, + }; + Fp x; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + x.setArray(tbl[i].buf, tbl[i].bufN); + CYBOZU_TEST_EQUAL(x, Fp(tbl[i].expected)); + } + uint32_t large[3] = { 0x234567a5, 0x00000001, 0x00100000}; + CYBOZU_TEST_EXCEPTION(x.setArray(large, 3), cybozu::Exception); +} + +void setArrayMaskTest1() +{ + char b1[] = { 0x56, 0x34, 0x12 }; + Fp x; + x.setArrayMask(b1, 3); + CYBOZU_TEST_EQUAL(x, 0x123456); + int b2[] = { 0x12, 0x34 }; + x.setArrayMask(b2, 2); + CYBOZU_TEST_EQUAL(x, Fp("0x3400000012")); +} + +void setArrayMaskTest2(mcl::fp::Mode mode) +{ + Fp::init("0x10000000000001234567a5", mode); + const struct { + uint32_t buf[3]; + size_t bufN; + const char *expected; + } tbl[] = { + { { 0x234567a4, 0x00000001, 0x00100000}, 1, "0x234567a4" }, + { { 0x234567a4, 0x00000001, 0x00100000}, 2, "0x1234567a4" }, + { { 0x234567a4, 0x00000001, 0x00100000}, 3, "0x10000000000001234567a4" }, + { { 0x234567a5, 0xfffffff1, 0xffffffff}, 3, "0x0ffffffffffff1234567a5" }, + }; + Fp x; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + x.setArrayMask(tbl[i].buf, tbl[i].bufN); + CYBOZU_TEST_EQUAL(x, Fp(tbl[i].expected)); + } +} + +void setArrayModTest() +{ + const mpz_class& p = Fp::getOp().mp; + const mpz_class tbl[] = { + 0, + 1, + p - 1, + p, + p + 1, + p * 2 - 1, + p * 2, + p * 2 + 1, + p * (p - 1) - 1, + p * (p - 1), + p * (p - 1) + 1, + p * p - 1, + p * p, + p * p + 1, + (mpz_class(1) << Fp::getOp().N * mcl::fp::UnitBitSize * 2) - 1, + }; + const size_t unitByteSize = sizeof(mcl::fp::Unit); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const mpz_class& x = tbl[i]; + const mcl::fp::Unit *px = mcl::gmp::getUnit(x); + const size_t xn = mcl::gmp::getUnitSize(x); + const size_t xByteSize = xn * unitByteSize; + const size_t fpByteSize = unitByteSize * Fp::getOp().N; + Fp y; + bool b; + y.setArray(&b, px, xn, mcl::fp::Mod); + bool expected = xByteSize <= fpByteSize * 2; + CYBOZU_TEST_EQUAL(b, expected); + if (!b) continue; + CYBOZU_TEST_EQUAL(y.getMpz(), x % p); + } +} + +CYBOZU_TEST_AUTO(set64bit) +{ + Fp::init("0x1000000000000000000f"); + const struct { + const char *p; + int64_t i; + } tbl[] = { + { "0x1234567812345678", int64_t(0x1234567812345678ull) }, + { "0xfffedcba987edcba997", -int64_t(0x1234567812345678ull) }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Fp x(tbl[i].p); + Fp y(tbl[i].i); + CYBOZU_TEST_EQUAL(x, y); + } +} + +void getUint64Test() +{ + const uint64_t tbl[] = { + 0, 1, 123, 0xffffffff, int64_t(0x7fffffffffffffffull) + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + uint64_t a = tbl[i]; + Fp x(a); + uint64_t b = x.getUint64(); + CYBOZU_TEST_ASSERT(!x.isNegative()); + CYBOZU_TEST_EQUAL(a, b); + } + { + Fp x("0xffffffffffffffff"); + CYBOZU_TEST_EQUAL(x.getUint64(), uint64_t(0xffffffffffffffffull)); + } + { + Fp x("0x10000000000000000"); + CYBOZU_TEST_EXCEPTION(x.getUint64(), cybozu::Exception); + x = -1; + CYBOZU_TEST_EXCEPTION(x.getUint64(), cybozu::Exception); + } + { + Fp x("0x10000000000000000"); + bool b = true; + CYBOZU_TEST_EQUAL(x.getUint64(&b), 0u); + CYBOZU_TEST_ASSERT(!b); + } +} + +void getInt64Test() +{ + const int64_t tbl[] = { + 0, 1, 123, 0xffffffff, int64_t(0x7fffffffffffffffull), + -1, -2, -12345678, int64_t(-9223372036854775808ull)/*-int64_t(1) << 63*/, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + int64_t a = tbl[i]; + Fp x(a); + CYBOZU_TEST_EQUAL(x.isNegative(), a < 0); + int64_t b = x.getInt64(); + CYBOZU_TEST_EQUAL(a, b); + } + { + Fp x("0x8000000000000000"); + CYBOZU_TEST_EXCEPTION(x.getInt64(), cybozu::Exception); + } + { + Fp x("0x8000000000000000"); + bool b = true; + CYBOZU_TEST_EQUAL(x.getInt64(&b), 0u); + CYBOZU_TEST_ASSERT(!b); + } +} + +void divBy2Test() +{ + const int tbl[] = { -4, -3, -2, -1, 0, 1, 2, 3 }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Fp x(tbl[i]), y; + Fp::divBy2(y, x); + y *= 2; + CYBOZU_TEST_EQUAL(y, x); + y = x; + Fp::divBy2(y, y); + y *= 2; + CYBOZU_TEST_EQUAL(y, x); + } +} + +void getStrTest() +{ + Fp x(0); + std::string str; + str = x.getStr(); + CYBOZU_TEST_EQUAL(str, "0"); + str = x.getStr(mcl::IoBinPrefix); + CYBOZU_TEST_EQUAL(str, "0b0"); + str = x.getStr(mcl::IoBin); + CYBOZU_TEST_EQUAL(str, "0"); + str = x.getStr(mcl::IoHexPrefix); + CYBOZU_TEST_EQUAL(str, "0x0"); + str = x.getStr(mcl::IoHex); + CYBOZU_TEST_EQUAL(str, "0"); + + x = 123; + str = x.getStr(); + CYBOZU_TEST_EQUAL(str, "123"); + str = x.getStr(mcl::IoBinPrefix); + CYBOZU_TEST_EQUAL(str, "0b1111011"); + str = x.getStr(mcl::IoBin); + CYBOZU_TEST_EQUAL(str, "1111011"); + str = x.getStr(mcl::IoHexPrefix); + CYBOZU_TEST_EQUAL(str, "0x7b"); + str = x.getStr(mcl::IoHex); + CYBOZU_TEST_EQUAL(str, "7b"); + + { + std::ostringstream os; + os << x; + CYBOZU_TEST_EQUAL(os.str(), "123"); + } + { + std::ostringstream os; + os << std::hex << std::showbase << x; + CYBOZU_TEST_EQUAL(os.str(), "0x7b"); + } + { + std::ostringstream os; + os << std::hex << x; + CYBOZU_TEST_EQUAL(os.str(), "7b"); + } + const char *tbl[] = { + "0x0", + "0x5", + "0x123", + "0x123456789012345679adbc", + "0xffffffff26f2fc170f69466a74defd8d", + "0x100000000000000000000000000000033", + "0x11ee12312312940000000000000000000000000002342343" + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const char *s = tbl[i]; + mpz_class mx(s); + if (mx >= Fp::getOp().mp) continue; + Fp y(s); + std::string xs, ys; + mcl::gmp::getStr(xs, mx, 16); + y.getStr(ys, 16); + CYBOZU_TEST_EQUAL(xs, ys); + } +} + +void setHashOfTest() +{ + const std::string msgTbl[] = { + "", "abc", "111111111111111111111111111111111111", + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(msgTbl); i++) { + size_t bitSize = Fp::getBitSize(); + std::string digest; + if (bitSize <= 256) { + digest = cybozu::Sha256().digest(msgTbl[i]); + } else { + digest = cybozu::Sha512().digest(msgTbl[i]); + } + Fp x, y; + x.setArrayMask(digest.c_str(), digest.size()); + y.setHashOf(msgTbl[i]); + CYBOZU_TEST_EQUAL(x, y); + } +} + +CYBOZU_TEST_AUTO(getArray) +{ + const struct { + const char *s; + uint32_t v[4]; + size_t vn; + } tbl[] = { + { "0", { 0, 0, 0, 0 }, 1 }, + { "1234", { 1234, 0, 0, 0 }, 1 }, + { "0xaabbccdd12345678", { 0x12345678, 0xaabbccdd, 0, 0 }, 2 }, + { "0x11112222333344445555666677778888", { 0x77778888, 0x55556666, 0x33334444, 0x11112222 }, 4 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + mpz_class x(tbl[i].s); + const size_t bufN = 8; + uint32_t buf[bufN]; + mcl::gmp::getArray(buf, bufN, x); + size_t n = mcl::fp::getNonZeroArraySize(buf, bufN); + CYBOZU_TEST_EQUAL(n, tbl[i].vn); + CYBOZU_TEST_EQUAL_ARRAY(buf, tbl[i].v, n); + } +} + +void serializeTest() +{ + const char *tbl[] = { "0", "-1", "123" }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + char buf[1024]; + Fp x, y; + x.setStr(tbl[i]); + size_t n = x.serialize(buf, sizeof(buf)); + CYBOZU_TEST_EQUAL(n, Fp::getByteSize()); + y.deserialize(buf, n); + CYBOZU_TEST_EQUAL(x, y); + + n = x.serialize(buf, sizeof(buf), mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(n, Fp::getByteSize() * 2); + y.deserialize(buf, n, mcl::IoSerializeHexStr); + CYBOZU_TEST_EQUAL(x, y); + } +} + +void modpTest() +{ + const mpz_class& p = Fp::getOp().mp; + const mpz_class tbl[] = { + 0, + 1, + p - 1, + p, + p + 1, + p * 2 - 1, + p * 2, + p * 2 + 1, + p * (p - 1) - 1, + p * (p - 1), + p * (p - 1) + 1, + p * p - 1, + p * p, + p * p + 1, + (mpz_class(1) << Fp::getOp().N * mcl::fp::UnitBitSize * 2) - 1, + }; + mcl::Modp modp; + modp.init(p); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const mpz_class& x = tbl[i]; + mpz_class r1, r2; + r1 = x % p; + modp.modp(r2, x); + CYBOZU_TEST_EQUAL(r1, r2); + } +} + +#include <iostream> +#if (defined(MCL_USE_LLVM) || defined(MCL_USE_XBYAK)) && (MCL_MAX_BIT_SIZE >= 521) +CYBOZU_TEST_AUTO(mod_NIST_P521) +{ + const size_t len = 521; + const size_t N = len / mcl::fp::UnitBitSize; + const char *tbl[] = { + "0", + "0xffffffff", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00111423424", + "0x11111111111111112222222222222222333333333333333344444444444444445555555555555555666666666666666677777777777777778888888888888888aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffff1234712341234123412341234123412341234", + "0x3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + }; + const char *p = "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + Fp::init(p, mcl::fp::FP_XBYAK); + const mpz_class mp(p); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + mpz_class mx(tbl[i]); + mcl::fp::Unit in[N * 2 + 1] = {}; + mcl::fp::Unit ok[N + 1]; + mcl::fp::Unit ex[N + 1]; + mcl::gmp::getArray(in, N * 2 + 1, mx); + mpz_class my = mx % mp; + mcl::gmp::getArray(ok, N + 1, my); +#ifdef MCL_USE_LLVM + mcl_fpDbl_mod_NIST_P521L(ex, in, Fp::getOp().p); + CYBOZU_TEST_EQUAL_ARRAY(ex, ok, N + 1); +#endif +#ifdef MCL_USE_XBYAK + const mcl::fp::Op& op = Fp::getOp(); + if (!op.isMont) { + op.fpDbl_mod(ex, in, op.p); + CYBOZU_TEST_EQUAL_ARRAY(ex, ok, N + 1); + } +#endif + } +} +#endif + +void sub(mcl::fp::Mode mode) +{ + printf("mode=%s\n", mcl::fp::ModeToStr(mode)); + const char *tbl[] = { + // N = 2 + "0x0000000000000001000000000000000d", + "0x7fffffffffffffffffffffffffffffff", + "0x8000000000000000000000000000001d", + "0xffffffffffffffffffffffffffffff61", + + // N = 3 + "0x000000000000000100000000000000000000000000000033", // min prime + "0x00000000fffffffffffffffffffffffffffffffeffffac73", + "0x0000000100000000000000000001b8fa16dfab9aca16b6b3", + "0x000000010000000000000000000000000000000000000007", + "0x30000000000000000000000000000000000000000000002b", + "0x70000000000000000000000000000000000000000000001f", + "0x800000000000000000000000000000000000000000000005", + "0xfffffffffffffffffffffffffffffffffffffffeffffee37", + "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", + "0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime + + // N = 4 + "0x0000000000000001000000000000000000000000000000000000000000000085", // min prime + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", + "0x7523648240000001ba344d80000000086121000000000013a700000000000017", + "0x800000000000000000000000000000000000000000000000000000000000005f", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime +#if MCL_MAX_BIT_SIZE >= 384 + + // N = 6 + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", +#endif + +#if MCL_MAX_BIT_SIZE >= 521 + // N = 9 + "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const char *pStr = tbl[i]; + printf("prime=%s\n", pStr); + Fp::init(pStr, mode); + cstrTest(); + setStrTest(); + streamTest(); + ioModeTest(); + edgeTest(); + convTest(); + compareTest(); + moduloTest(pStr); + opeTest(); + mulUnitTest(); + powTest(); + powNegTest(); + powFpTest(); + powGmp(); + setArrayTest1(); + setArrayMaskTest1(); + setArrayModTest(); + getUint64Test(); + getInt64Test(); + divBy2Test(); + getStrTest(); + setHashOfTest(); + serializeTest(); + modpTest(); + } + anotherFpTest(mode); + setArrayTest2(mode); + setArrayMaskTest2(mode); +} + +std::string g_mode; + +CYBOZU_TEST_AUTO(main) +{ + if (g_mode.empty() || g_mode == "auto") { + sub(mcl::fp::FP_AUTO); + } + if (g_mode.empty() || g_mode == "gmp") { + sub(mcl::fp::FP_GMP); + } + if (g_mode.empty() || g_mode == "gmp_mont") { + sub(mcl::fp::FP_GMP_MONT); + } +#ifdef MCL_USE_LLVM + if (g_mode.empty() || g_mode == "llvm") { + sub(mcl::fp::FP_LLVM); + } + if (g_mode.empty() || g_mode == "llvm_mont") { + sub(mcl::fp::FP_LLVM_MONT); + } +#endif +#ifdef MCL_USE_XBYAK + if (g_mode.empty() || g_mode == "xbyak") { + sub(mcl::fp::FP_XBYAK); + } +#endif +} + +CYBOZU_TEST_AUTO(copyUnitToByteAsLE) +{ + using namespace mcl::fp; +#if MCL_SIZEOF_UNIT == 4 + const Unit src[] = { 0x12345678, 0xaabbccdd, 0xffeeddcc, 0x87654321 }; +#else + const Unit src[] = { uint64_t(0xaabbccdd12345678ull), uint64_t(0x87654321ffeeddcc) }; +#endif + const uint8_t ok[] = { 0x78, 0x56, 0x34, 0x12, 0xdd, 0xcc, 0xbb, 0xaa, 0xcc, 0xdd, 0xee, 0xff, 0x21, 0x43, 0x65, 0x87 }; + const size_t okN = CYBOZU_NUM_OF_ARRAY(ok); + for (size_t i = 0; i < okN; i++) { + uint8_t buf[okN] = {}; + copyUnitToByteAsLE(buf, src, i); + CYBOZU_TEST_EQUAL_ARRAY(ok, buf, i); + } + mcl::fp::Unit dst[2]; + for (size_t i = 1; i <= sizeof(dst); i++) { + memset(dst, 0xff, sizeof(dst)); + mcl::fp::copyByteToUnitAsLE(dst, ok, i); + if (i < sizeof(Unit)) { + CYBOZU_TEST_EQUAL(src[0] & ((uint64_t(1) << (i * 8)) - 1), dst[0]); + CYBOZU_TEST_EQUAL(dst[1], Unit(-1)); + continue; + } + CYBOZU_TEST_EQUAL(dst[0], src[0]); + if (i == sizeof(Unit)) { + CYBOZU_TEST_EQUAL(dst[1], Unit(-1)); + continue; + } + if (i < sizeof(dst)) { + CYBOZU_TEST_EQUAL(src[1] & ((uint64_t(1) << ((i - sizeof(Unit)) * 8)) - 1), dst[1]); + continue; + } + CYBOZU_TEST_EQUAL(src[1], dst[1]); + } + dst[0] = 1; + copyByteToUnitAsLE(dst, ok, 0); + CYBOZU_TEST_EQUAL(dst[0], 1u); +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + opt.appendOpt(&g_mode, "", "m", ": mode(auto/gmp/gmp_mont/llvm/llvm_mont/xbyak)"); + opt.appendHelp("h", ": show this message"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + return cybozu::test::autoRun.run(argc, argv); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/fp_tower_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/fp_tower_test.cpp new file mode 100644 index 000000000..a7123f7a5 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/fp_tower_test.cpp @@ -0,0 +1,477 @@ +#define PUT(x) std::cout << #x "=" << (x) << std::endl +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/xorshift.hpp> +#include <time.h> +#include <mcl/fp.hpp> +#include <mcl/fp_tower.hpp> + +#ifdef _MSC_VER + #pragma warning(disable : 4456) +#endif + +#if MCL_MAX_BIT_SIZE >= 768 +typedef mcl::FpT<mcl::FpTag, MCL_MAX_BIT_SIZE> Fp; +#else +typedef mcl::FpT<mcl::FpTag, 384> Fp; +#endif +typedef mcl::Fp2T<Fp> Fp2; +typedef mcl::FpDblT<Fp> FpDbl; +typedef mcl::Fp6T<Fp> Fp6; +typedef mcl::Fp12T<Fp> Fp12; + +bool g_benchOnly = false; + +void testFp2() +{ + using namespace mcl; + puts(__FUNCTION__); +#if MCL_MAX_BIT_SIZE < 768 + const size_t FpSize = 48; + CYBOZU_TEST_EQUAL(sizeof(Fp), FpSize); + CYBOZU_TEST_EQUAL(sizeof(Fp2), FpSize * 2); + CYBOZU_TEST_EQUAL(sizeof(Fp6), FpSize * 6); + CYBOZU_TEST_EQUAL(sizeof(Fp12), FpSize * 12); +#endif + Fp2 x, y, z; + x.a = 1; + x.b = 2; + + { + std::stringstream os; + os << x; + os >> y; + CYBOZU_TEST_EQUAL(x, y); + } + y.a = 3; + y.b = 4; + /* + x = 1 + 2i + y = 3 + 4i + */ + Fp2::add(z, x, y); + CYBOZU_TEST_EQUAL(z, Fp2(4, 6)); + Fp2::sub(z, x, y); + CYBOZU_TEST_EQUAL(z, Fp2(-2, -2)); + Fp2::mul(z, x, y); + /* + (1 + 2i)(3 + 4i) = (3 - 8) + (4 + 6)i = -5 + 10i + */ + CYBOZU_TEST_EQUAL(z, Fp2(-5, 10)); + Fp2::neg(z, z); + CYBOZU_TEST_EQUAL(z, Fp2(5, -10)); + /* + xi = xi_a + i + (1 - 2i)(xi_a + i) = (xi_a + 2) + (1 - 2 xi_a)i + */ + z = Fp2(1, -2); + Fp2::mul_xi(z, z); + Fp a = Fp2::get_xi_a(); + CYBOZU_TEST_EQUAL(z, Fp2(a + 2, a * (-2) + 1)); + z = x * x; + Fp2::sqr(y, x); + CYBOZU_TEST_EQUAL(z, y); + x.a = -123456789; + x.b = 464652165165; + y = x * x; + Fp2::sqr(x, x); + CYBOZU_TEST_EQUAL(x, y); + { + std::ostringstream oss; + oss << x; + std::istringstream iss(oss.str()); + Fp2 w; + iss >> w; + CYBOZU_TEST_EQUAL(x, w); + } + y = 1; + for (int i = 0; i < 10; i++) { + Fp2::pow(z, x, i); + CYBOZU_TEST_EQUAL(z, y); + y *= x; + } + /* + (a + bi)^p = a + bi if p % 4 = 1 + (a + bi)^p = a - bi if p % 4 = 3 + */ + { + const mpz_class& mp = Fp::getOp().mp; + y = x; + Fp2::pow(z, y, mp); + if ((mp % 4) == 3) { + Fp::neg(z.b, z.b); + } + CYBOZU_TEST_EQUAL(z, y); + } + { + mpz_class t = Fp::getOp().mp; + t /= 2; + Fp x; + x.setMpz(t); + CYBOZU_TEST_EQUAL(x * 2, Fp(-1)); + t += 1; + x.setMpz(t); + CYBOZU_TEST_EQUAL(x * 2, 1); + } + { + Fp2 a(1, 1); + Fp2 b(1, -1); + Fp2 c(Fp2(2) / a); + CYBOZU_TEST_EQUAL(c, b); + CYBOZU_TEST_EQUAL(a * b, Fp2(2)); + CYBOZU_TEST_EQUAL(a * c, Fp2(2)); + } + y = x; + Fp2::inv(y, x); + y *= x; + CYBOZU_TEST_EQUAL(y, 1); + + // square root + for (int i = 0; i < 3; i++) { + x.a = i * i + i * 2; + x.b = i; + Fp2::sqr(y, x); + CYBOZU_TEST_ASSERT(Fp2::squareRoot(z, y)); + CYBOZU_TEST_EQUAL(z * z, y); + CYBOZU_TEST_ASSERT(Fp2::squareRoot(y, y)); + CYBOZU_TEST_EQUAL(z * z, y * y); + x.b = 0; + Fp2::sqr(y, x); + CYBOZU_TEST_ASSERT(Fp2::squareRoot(z, y)); + CYBOZU_TEST_EQUAL(z * z, y); + x.a = 0; + x.b = i * i + i * 3; + Fp2::sqr(y, x); + CYBOZU_TEST_ASSERT(Fp2::squareRoot(z, y)); + CYBOZU_TEST_EQUAL(z * z, y); + } +} + +void testFp6sqr(const Fp2& a, const Fp2& b, const Fp2& c, const Fp6& x) +{ + Fp2 t; + t = b * c * 2; + Fp2::mul_xi(t, t); + t += a * a; + CYBOZU_TEST_EQUAL(x.a, t); + t = c * c; + Fp2::mul_xi(t, t); + t += a * b * 2; + CYBOZU_TEST_EQUAL(x.b, t); + t = b * b + a * c * 2; + CYBOZU_TEST_EQUAL(x.c, t); +} + +void testFp6() +{ + using namespace mcl; + puts(__FUNCTION__); + Fp2 a(1, 2), b(3, 4), c(5, 6); + Fp6 x(a, b, c); + Fp6 y(Fp2(-1, 1), Fp2(4, -3), Fp2(-6, 2)); + Fp6 z, w; + { + std::stringstream ss; + ss << x; + ss >> z; + CYBOZU_TEST_EQUAL(x, z); + } + Fp6::add(z, x, y); + CYBOZU_TEST_EQUAL(z, Fp6(Fp2(0, 3), Fp2(7, 1), Fp2(-1, 8))); + Fp6::sub(z, x, y); + CYBOZU_TEST_EQUAL(z, Fp6(Fp2(2, 1), Fp2(-1, 7), Fp2(11, 4))); + Fp6::neg(z, x); + CYBOZU_TEST_EQUAL(z, Fp6(-a, -b, -c)); + Fp6::sqr(z, x); + Fp6::mul(w, x, x); + testFp6sqr(a, b, c, z); + testFp6sqr(a, b, c, w); + z = x; + Fp6::sqr(z, z); + Fp6::mul(w, x, x); + testFp6sqr(a, b, c, z); + testFp6sqr(a, b, c, w); + for (int i = 0; i < 10; i++) { + Fp6::inv(y, x); + Fp6::mul(z, y, x); + CYBOZU_TEST_EQUAL(z, 1); + x += y; + y = x; + Fp6::inv(y, y); + y *= x; + CYBOZU_TEST_EQUAL(y, 1); + } +} + +void testFp12() +{ + puts(__FUNCTION__); + Fp6 xa(Fp2(1, 2), Fp2(3, 4), Fp2(5, 6)); + Fp6 xb(Fp2(3, 1), Fp2(6, -1), Fp2(-2, 5)); + Fp12 x(xa, xb); + Fp6 ya(Fp2(2, 1), Fp2(5, 3), Fp2(4, 1)); + Fp6 yb(Fp2(1, -3), Fp2(2, -1), Fp2(-3, 1)); + Fp12 y(ya, yb); + Fp12 z; + Fp12::add(z, x, y); + CYBOZU_TEST_EQUAL(z, Fp12(Fp6(Fp2(3, 3), Fp2(8, 7), Fp2(9, 7)), Fp6(Fp2(4, -2), Fp2(8, -2), Fp2(-5, 6)))); + Fp12::sub(z, x, y); + CYBOZU_TEST_EQUAL(z, Fp12(Fp6(Fp2(-1, 1), Fp2(-2, 1), Fp2(1, 5)), Fp6(Fp2(2, 4), Fp2(4, 0), Fp2(1, 4)))); + Fp12::neg(z, x); + CYBOZU_TEST_EQUAL(z, Fp12(-xa, -xb)); + + y.b.clear(); + z = y; + Fp12::sqr(z, z); + CYBOZU_TEST_EQUAL(z.a, y.a * y.a); + z = y * y; + CYBOZU_TEST_EQUAL(z.a, y.a * y.a); + CYBOZU_TEST_ASSERT(z.b.isZero()); + Fp12 w; + y = x; + z = x * x; + w = x; + Fp12::sqr(w, w); + CYBOZU_TEST_EQUAL(z, w); + y = x; + y *= y; + Fp12::sqr(x, x); + CYBOZU_TEST_EQUAL(x, y); + for (int i = 0; i < 10; i++) { + w = x; + Fp12::inv(w, w); + Fp12::mul(y, w, x); + CYBOZU_TEST_EQUAL(y, 1); + x += y; + } +} + +void testFpDbl() +{ + puts(__FUNCTION__); + { + std::string pstr; + Fp::getModulo(pstr); + mpz_class mp(pstr); + mp <<= Fp::getUnitSize() * mcl::fp::UnitBitSize; + mpz_class mp1 = mp - 1; + mcl::gmp::getStr(pstr, mp1); + const char *tbl[] = { + "0", "1", "123456", "123456789012345668909", pstr.c_str(), + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + mpz_class mx(tbl[i]); + FpDbl x; + x.setMpz(mx); + for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(tbl); j++) { + FpDbl y, z; + mpz_class mz, mo; + mpz_class my(tbl[j]); + y.setMpz(my); + FpDbl::add(z, x, y); + mcl::gmp::addMod(mo, mx, my, mp); + z.getMpz(mz); + CYBOZU_TEST_EQUAL(mz, mo); + mcl::gmp::subMod(mo, mx, my, mp); + FpDbl::sub(z, x, y); + z.getMpz(mz); + CYBOZU_TEST_EQUAL(mz, mo); + if (!Fp::isFullBit()) { + FpDbl::addPre(z, x, y); + mo = mx + my; + z.getMpz(mz); + CYBOZU_TEST_EQUAL(mz, mo); + if (mx >= my) { + FpDbl::subPre(z, x, y); + mo = mx - my; + z.getMpz(mz); + CYBOZU_TEST_EQUAL(mz, mo); + } + } + } + } + } + { + std::string pstr; + Fp::getModulo(pstr); + const mpz_class mp(pstr); + cybozu::XorShift rg; + for (int i = 0; i < 3; i++) { + Fp x, y, z; + mpz_class mx, my, mz, mo; + x.setRand(rg); + y.setRand(rg); + x.getMpz(mx); + y.getMpz(my); + FpDbl d; + FpDbl::mulPre(d, x, y); + d.getMpz(mz); + { + Fp tx, ty; + tx = x; + ty = y; + tx.toMont(); + ty.toMont(); + mpz_class mtx, mty; + tx.getMpz(mtx); + ty.getMpz(mty); + mo = mtx * mty; + } + CYBOZU_TEST_EQUAL(mz, mo); + + FpDbl::mod(z, d); + z.getMpz(mz); + mo = (mx * my) % mp; + CYBOZU_TEST_EQUAL(mz, mo); + CYBOZU_TEST_EQUAL(z, x * y); + + FpDbl::sqrPre(d, x); + d.getMpz(mz); + { + Fp tx; + tx = x; + tx.toMont(); + mpz_class mtx; + tx.getMpz(mtx); + mo = mtx * mtx; + } + CYBOZU_TEST_EQUAL(mz, mo); + + FpDbl::mod(z, d); + z.getMpz(mz); + mo = (mx * mx) % mp; + CYBOZU_TEST_EQUAL(mz, mo); + CYBOZU_TEST_EQUAL(z, x * x); + } + } +} + +void testIo() +{ + int modeTbl[] = { 0, 2, 2 | mcl::IoPrefix, 10, 16, 16 | mcl::IoPrefix, mcl::IoArray, mcl::IoArrayRaw }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(modeTbl); i++) { + int ioMode = modeTbl[i]; + Fp12 x; + for (int j = 0; j < 12; j++) { + x.getFp0()[j] = j * j; + } + std::string s = x.getStr(ioMode); + Fp12 y; + y.setStr(s, ioMode); + CYBOZU_TEST_EQUAL(x, y); + } +} + +void benchFp2() +{ + puts(__FUNCTION__); + Fp2 x, y; + x.a.setStr("4"); + x.b.setStr("464652165165"); + y = x * x; + double addT, subT, mulT, sqrT, invT, mul_xiT; + CYBOZU_BENCH_T(addT, Fp2::add, x, x, y); + CYBOZU_BENCH_T(subT, Fp2::sub, x, x, y); + CYBOZU_BENCH_T(mulT, Fp2::mul, x, x, y); + CYBOZU_BENCH_T(sqrT, Fp2::sqr, x, x); + CYBOZU_BENCH_T(invT, Fp2::inv, x, x); + CYBOZU_BENCH_T(mul_xiT, Fp2::mul_xi, x, x); +// CYBOZU_BENCH("Fp2::mul_Fp_0", Fp2::mul_Fp_0, x, x, Param::half); +// CYBOZU_BENCH("Fp2::mul_Fp_1", Fp2::mul_Fp_1, x, Param::half); +// CYBOZU_BENCH("Fp2::divBy2 ", Fp2::divBy2, x, x); +// CYBOZU_BENCH("Fp2::divBy4 ", Fp2::divBy4, x, x); + printf("add %8.2f|sub %8.2f|mul %8.2f|sqr %8.2f|inv %8.2f|mul_xi %8.2f\n", addT, subT, mulT, sqrT, invT, mul_xiT); +} + +void test(const char *p, mcl::fp::Mode mode) +{ + const int xi_a = 1; + Fp::init(xi_a, p, mode); + printf("mode=%s\n", mcl::fp::ModeToStr(mode)); + Fp2::init(); +#if 0 + if (Fp::getBitSize() > 256) { + printf("not support p=%s\n", p); + return; + } +#endif + if (g_benchOnly) { + benchFp2(); + return; + } + testFp2(); + testFpDbl(); + testFp6(); + testFp12(); + testIo(); +} + +void testAll() +{ + const char *tbl[] = { + // N = 2 + "0x0000000000000001000000000000000d", + "0x7fffffffffffffffffffffffffffffff", + "0x8000000000000000000000000000001d", + "0xffffffffffffffffffffffffffffff61", + + // N = 3 + "0x000000000000000100000000000000000000000000000033", // min prime + "0x00000000fffffffffffffffffffffffffffffffeffffac73", + "0x0000000100000000000000000001b8fa16dfab9aca16b6b3", + "0x000000010000000000000000000000000000000000000007", + "0x30000000000000000000000000000000000000000000002b", + "0x70000000000000000000000000000000000000000000001f", + "0x800000000000000000000000000000000000000000000005", + "0xfffffffffffffffffffffffffffffffeffffffffffffffff", + "0xfffffffffffffffffffffffffffffffffffffffeffffee37", + "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", + "0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime + + // N = 4 + "0x0000000000000001000000000000000000000000000000000000000000000085", // min prime + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", + "0x7523648240000001ba344d80000000086121000000000013a700000000000017", + "0x800000000000000000000000000000000000000000000000000000000000005f", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime +#if MCL_MAX_BIT_SIZE >= 384 + // N = 6 + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", +#endif +#if MCL_MAX_BIT_SIZE >= 768 + "776259046150354467574489744231251277628443008558348305569526019013025476343188443165439204414323238975243865348565536603085790022057407195722143637520590569602227488010424952775132642815799222412631499596858234375446423426908029627", +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const char *p = tbl[i]; + printf("prime=%s %d\n", p, (int)(strlen(p) - 2) * 4); + test(p, mcl::fp::FP_GMP); +#ifdef MCL_USE_LLVM + test(p, mcl::fp::FP_LLVM); + test(p, mcl::fp::FP_LLVM_MONT); +#endif +#ifdef MCL_USE_XBYAK + test(p, mcl::fp::FP_XBYAK); +#endif + } +} + +CYBOZU_TEST_AUTO(testAll) +{ + testAll(); +} + +int main(int argc, char *argv[]) +{ + if (argc > 1 && strcmp(argv[1], "-bench") == 0) { + g_benchOnly = true; + } + if (g_benchOnly) { + testAll(); + return 0; + } else { + return cybozu::test::autoRun.run(argc, argv); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/fp_util_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/fp_util_test.cpp new file mode 100644 index 000000000..e8a9f9aa5 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/fp_util_test.cpp @@ -0,0 +1,270 @@ +#define PUT(x) std::cout << #x "=" << (x) << std::endl +#include <cybozu/test.hpp> +#include <mcl/conversion.hpp> +#include <mcl/gmp_util.hpp> +#include <mcl/fp.hpp> +#include <vector> + +CYBOZU_TEST_AUTO(arrayToHex) +{ + const struct { + uint32_t x[4]; + size_t n; + const char *str; + } tbl[] = { + { { 0, 0, 0, 0 }, 0, "0" }, + { { 0x123, 0, 0, 0 }, 1, "123" }, + { { 0x12345678, 0xaabbcc, 0, 0 }, 2, "aabbcc12345678" }, + { { 0, 0x12, 0x234a, 0 }, 3, "234a0000001200000000" }, + { { 1, 2, 0xffffffff, 0x123abc }, 4, "123abcffffffff0000000200000001" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + char buf[64]; + size_t n = mcl::fp::arrayToHex(buf, sizeof(buf), tbl[i].x, tbl[i].n, false); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, tbl[i].str, n); + n = mcl::fp::arrayToHex(buf, sizeof(buf), tbl[i].x, tbl[i].n, true); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, (std::string("0x") + tbl[i].str).c_str(), n); + } +} + +CYBOZU_TEST_AUTO(arrayToBin) +{ + const struct { + uint32_t x[4]; + size_t n; + const char *str; + } tbl[] = { + { { 0, 0, 0, 0 }, 0, "0" }, + { { 0x123, 0, 0, 0 }, 1, "100100011" }, + { { 0x12345678, 0xaabbcc, 0, 0 }, 2, "10101010101110111100110000010010001101000101011001111000" }, + { { 0, 0x12, 0x234a, 0 }, 3, "100011010010100000000000000000000000000001001000000000000000000000000000000000" }, + { { 1, 2, 0xffffffff, 0x123abc }, 4, "100100011101010111100111111111111111111111111111111110000000000000000000000000000001000000000000000000000000000000001" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + char buf[512]; + size_t n = mcl::fp::arrayToBin(buf, sizeof(buf), tbl[i].x, tbl[i].n, false); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, tbl[i].str, n); + n = mcl::fp::arrayToBin(buf, sizeof(buf), tbl[i].x, tbl[i].n, true); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL_ARRAY(buf + sizeof(buf) - n, (std::string("0b") + tbl[i].str).c_str(), n); + } +} +// CYBOZU_TEST_AUTO(verifyStr) // QQQ + +CYBOZU_TEST_AUTO(hexToArray) +{ + const struct { + const char *str; + uint64_t x[4]; + } tbl[] = { + { "0", { 0, 0, 0, 0 } }, + { "5", { 5, 0, 0, 0 } }, + { "123", { 0x123, 0, 0, 0 } }, + { "123456789012345679adbc", { uint64_t(0x789012345679adbcull), 0x123456, 0, 0 } }, + { "ffffffff26f2fc170f69466a74defd8d", { uint64_t(0x0f69466a74defd8dull), uint64_t(0xffffffff26f2fc17ull), 0, 0 } }, + { "100000000000000000000000000000033", { uint64_t(0x0000000000000033ull), 0, 1, 0 } }, + { "11ee12312312940000000000000000000000000002342343", { uint64_t(0x0000000002342343ull), uint64_t(0x0000000000000000ull), uint64_t(0x11ee123123129400ull), 0 } }, + { "1234567890abcdefABCDEF123456789aba32134723424242424", { uint64_t(0x2134723424242424ull), uint64_t(0xDEF123456789aba3ull), uint64_t(0x4567890abcdefABCull), 0x123 } }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const size_t xN = 4; + uint64_t x[xN]; + size_t n = mcl::fp::hexToArray(x, xN, tbl[i].str, strlen(tbl[i].str)); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL_ARRAY(x, tbl[i].x, n); + } +} + +CYBOZU_TEST_AUTO(compareArray) +{ + const struct { + uint32_t a[4]; + uint32_t b[4]; + size_t n; + int expect; + } tbl[] = { + { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0 }, + { { 1, 0, 0, 0 }, { 0, 0, 0, 0 }, 1, 1 }, + { { 0, 0, 0, 0 }, { 1, 0, 0, 0 }, 1, -1 }, + { { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, 1, 0 }, + { { 3, 1, 1, 0 }, { 2, 1, 1, 0 }, 4, 1 }, + { { 9, 2, 1, 1 }, { 1, 3, 1, 1 }, 4, -1 }, + { { 1, 7, 8, 4 }, { 1, 7, 8, 9 }, 3, 0 }, + { { 1, 7, 8, 4 }, { 1, 7, 8, 9 }, 4, -1 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + int e = mcl::fp::compareArray(tbl[i].a, tbl[i].b, tbl[i].n); + CYBOZU_TEST_EQUAL(e, tbl[i].expect); + } +} + +CYBOZU_TEST_AUTO(isLessArray) +{ + const struct { + uint32_t a[4]; + uint32_t b[4]; + size_t n; + bool expect; + } tbl[] = { + { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, false }, + { { 1, 0, 0, 0 }, { 0, 0, 0, 0 }, 1, false }, + { { 0, 0, 0, 0 }, { 1, 0, 0, 0 }, 1, true }, + { { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, 1, false }, + { { 3, 1, 1, 0 }, { 2, 1, 1, 0 }, 4, false }, + { { 3, 1, 2, 0 }, { 2, 2, 2, 0 }, 4, true }, + { { 9, 2, 1, 1 }, { 1, 3, 1, 1 }, 4, true }, + { { 1, 7, 8, 4 }, { 1, 7, 8, 9 }, 3, false }, + { { 1, 7, 8, 4 }, { 1, 7, 8, 9 }, 4, true }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + bool e = mcl::fp::isLessArray(tbl[i].a, tbl[i].b, tbl[i].n); + CYBOZU_TEST_EQUAL(e, tbl[i].expect); + e = mcl::fp::isGreaterArray(tbl[i].b, tbl[i].a, tbl[i].n); + CYBOZU_TEST_EQUAL(e, tbl[i].expect); + } +} + +CYBOZU_TEST_AUTO(isLessOrEqualArray) +{ + const struct { + uint32_t a[4]; + uint32_t b[4]; + size_t n; + bool expect; + } tbl[] = { + { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, true }, + { { 1, 0, 0, 0 }, { 0, 0, 0, 0 }, 1, false }, + { { 0, 0, 0, 0 }, { 1, 0, 0, 0 }, 1, true }, + { { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, 1, true }, + { { 3, 1, 1, 0 }, { 2, 1, 1, 0 }, 4, false }, + { { 3, 1, 2, 0 }, { 2, 2, 2, 0 }, 4, true }, + { { 9, 2, 1, 1 }, { 1, 3, 1, 1 }, 4, true }, + { { 1, 7, 8, 4 }, { 1, 7, 8, 9 }, 3, true }, + { { 1, 7, 8, 4 }, { 1, 7, 8, 9 }, 4, true }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + bool e = mcl::fp::isLessOrEqualArray(tbl[i].a, tbl[i].b, tbl[i].n); + CYBOZU_TEST_EQUAL(e, tbl[i].expect); + e = mcl::fp::isGreaterOrEqualArray(tbl[i].b, tbl[i].a, tbl[i].n); + CYBOZU_TEST_EQUAL(e, tbl[i].expect); + } +} + +struct Rand { + std::vector<uint32_t> v; + const uint8_t *p; + size_t pos; + size_t endPos; + void read(bool *pb, void *x, size_t n) + { + if (pos + n > endPos) { + *pb = false; + return; + } + uint8_t *dst = (uint8_t*)x; + memcpy(dst, p + pos, n); + pos += n; + *pb = true; + } + void read(void *x, size_t n) + { + bool b; + read(&b, x, n); + if (!b) throw cybozu::Exception("Rand") << n; + } + uint32_t operator()() + { + char buf[4]; + read(buf, 4); + uint32_t v; + memcpy(&v, buf, 4); + return v; + } + Rand(const uint32_t *x, size_t n) + : p(0) + , pos(0) + { + for (size_t i = 0; i < n; i++) { + v.push_back(x[i]); + } + p = (uint8_t*)&v[0]; + endPos = v.size() * 4; + } +}; + +CYBOZU_TEST_AUTO(maskArray) +{ +#if 1 + const size_t n = 2; + uint32_t org[n] = { 0xabce1234, 0xffffef32 }; + for (size_t i = 0; i <= sizeof(org) * 8; i++) { + uint32_t x[n]; + memcpy(x, org, sizeof(org)); + mcl::fp::maskArray(x, n, i); + mpz_class t; + mcl::gmp::setArray(t, org, n); + t &= (mpz_class(1) << i) - 1; + uint32_t y[n]; + mcl::gmp::getArray(y, n, t); + CYBOZU_TEST_EQUAL_ARRAY(x, y, n); + } +#else + const size_t n = 4; + uint16_t org[n] = { 0x1234, 0xabce, 0xef32, 0xffff }; + for (size_t i = 0; i <= sizeof(org) * 8; i++) { + uint16_t x[n]; + memcpy(x, org, sizeof(org)); + mcl::fp::maskArray(x, n, i); + mpz_class t; + mcl::gmp::setArray(t, org, n); + t &= (mpz_class(1) << i) - 1; + uint16_t y[n]; + mcl::gmp::getArray(y, n, t); + CYBOZU_TEST_EQUAL_ARRAY(x, y, n); + } +#endif +} + +CYBOZU_TEST_AUTO(stream) +{ + const char *nulTbl[] = { "", " ", " \t\t\n\n " }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(nulTbl); i++) { + const char *p = nulTbl[i]; + cybozu::MemoryInputStream is(p, strlen(p)); + std::string w = "abc"; + mcl::fp::local::loadWord(w, is); + CYBOZU_TEST_ASSERT(w.empty()); + } + const struct { + const char *buf; + const char *expect[2]; + size_t n; + } tbl[] = { + { "\t\t \n\rabc\r\r\n def", { "abc", "def" }, 2 }, + { "123", { "123" }, 1 }, + { "123\n", { "123" }, 1 }, + { "123 456", { "123", "456" }, 2 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const char *buf = tbl[i].buf; + { + cybozu::MemoryInputStream is(buf, strlen(buf)); + for (size_t j = 0; j < tbl[i].n; j++) { + std::string w; + mcl::fp::local::loadWord(w, is); + CYBOZU_TEST_EQUAL(w, tbl[i].expect[j]); + } + } + { + std::istringstream is(buf); + for (size_t j = 0; j < tbl[i].n; j++) { + std::string w; + mcl::fp::local::loadWord(w, is); + CYBOZU_TEST_EQUAL(w, tbl[i].expect[j]); + } + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/glv_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/glv_test.cpp new file mode 100644 index 000000000..a917f51f4 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/glv_test.cpp @@ -0,0 +1,209 @@ +#define PUT(x) std::cout << #x "=" << (x) << std::endl; +#include <cybozu/test.hpp> +#include <cybozu/xorshift.hpp> +#include <cybozu/benchmark.hpp> + +#if 1 +#include <mcl/bn384.hpp> +using namespace mcl::bn384; +#else +#include <mcl/bn256.hpp> +using namespace mcl::bn256; +#endif + +#define PUT(x) std::cout << #x "=" << (x) << std::endl; + +/* + Skew Frobenius Map and Efficient Scalar Multiplication for Pairing-Based Cryptography + Y. Sakemi, Y. Nogami, K. Okeya, H. Kato, Y. Morikawa +*/ +struct oldGLV { + Fp w; // (-1 + sqrt(-3)) / 2 + mpz_class r; + mpz_class v; // 6z^2 + 4z + 1 > 0 + mpz_class c; // 2z + 1 + void init(const mpz_class& r, const mpz_class& z) + { + if (!Fp::squareRoot(w, -3)) throw cybozu::Exception("oldGLV:init"); + w = (w - 1) / 2; + this->r = r; + v = 1 + z * (4 + z * 6); + c = 2 * z + 1; + } + /* + (p^2 mod r) (x, y) = (wx, -y) + */ + void mulP2(G1& Q, const G1& P) const + { + Fp::mul(Q.x, P.x, w); + Fp::neg(Q.y, P.y); + Q.z = P.z; + } + /* + x = ap^2 + b mod r + assume(x < r); + */ + void split(mpz_class& a, mpz_class& b, const mpz_class& x) const + { + assert(0 < x && x < r); + /* + x = s1 * v + s2 // s1 = x / v, s2 = x % v + = s1 * c * p^2 + s2 // vP = cp^2 P + = (s3 * v + s4) * p^2 + s2 // s3 = (s1 * c) / v, s4 = (s1 * c) % v + = (s3 * c * p^2 + s4) * p^2 + s2 + = (s3 * c) * p^4 + s4 * p^2 + s2 // s5 = s3 * c, p^4 = p^2 - 1 + = s5 * (p^2 - 1) + s4 * p^2 + s2 + = (s4 + s5) * p^2 + (s2 - s5) + */ + mpz_class t; + mcl::gmp::divmod(a, t, x, v); // a = t / v, t = t % v + a *= c; + mcl::gmp::divmod(b, a, a, v); // b = a / v, a = a % v + b *= c; + a += b; + b = t - b; + } + template<class G1> + void mul(G1& Q, const G1& P, const mpz_class& x) const + { + G1 A, B; + mpz_class a, b; + split(a, b, x); + mulP2(A, P); + G1::mul(A, A, a); + G1::mul(B, P, b); + G1::add(Q, A, B); + } +}; + +template<class GLV1, class GLV2> +void compareLength(const GLV1& rhs, const GLV2& lhs) +{ + cybozu::XorShift rg; + int lt = 0; + int eq = 0; + int gt = 0; + mpz_class R0, R1, L0, L1, x; + Fr r; + for (int i = 1; i < 1000; i++) { + r.setRand(rg); + x = r.getMpz(); + rhs.split(R0, R1, x); + lhs.split(L0, L1, x); + + size_t R0n = mcl::gmp::getBitSize(R0); + size_t R1n = mcl::gmp::getBitSize(R1); + size_t L0n = mcl::gmp::getBitSize(L0); + size_t L1n = mcl::gmp::getBitSize(L1); + size_t Rn = std::max(R0n, R1n); + size_t Ln = std::max(L0n, L1n); + if (Rn == Ln) { + eq++; + } + if (Rn > Ln) { + gt++; + } + if (Rn < Ln) { + lt++; + } + } + printf("#of{<} = %d, #of{=} = %d #of{>} = %d\n", lt, eq, gt); +} + +void testGLV1() +{ + G1 P0, P1, P2; + mapToG1(P0, 1); + cybozu::XorShift rg; + + oldGLV oldGlv; + if (!BN::param.isBLS12) { + oldGlv.init(BN::param.r, BN::param.z); + } + + mcl::bn::local::GLV1 glv; + glv.init(BN::param.r, BN::param.z, BN::param.isBLS12); + if (!BN::param.isBLS12) { + compareLength(glv, oldGlv); + } + + for (int i = 1; i < 100; i++) { + mapToG1(P0, i); + Fr s; + s.setRand(rg); + mpz_class ss = s.getMpz(); + G1::mulGeneric(P1, P0, ss); + glv.mul(P2, P0, ss); + CYBOZU_TEST_EQUAL(P1, P2); + glv.mul(P2, P0, ss, true); + CYBOZU_TEST_EQUAL(P1, P2); + if (!BN::param.isBLS12) { + oldGlv.mul(P2, P0, ss); + CYBOZU_TEST_EQUAL(P1, P2); + } + } + for (int i = -100; i < 100; i++) { + mpz_class ss = i; + G1::mulGeneric(P1, P0, ss); + glv.mul(P2, P0, ss); + CYBOZU_TEST_EQUAL(P1, P2); + glv.mul(P2, P0, ss, true); + CYBOZU_TEST_EQUAL(P1, P2); + } + Fr s; + mapToG1(P0, 123); + CYBOZU_BENCH_C("Ec::mul", 100, P1 = P0; s.setRand(rg); G1::mulGeneric, P2, P1, s.getMpz()); + CYBOZU_BENCH_C("Ec::glv", 100, P1 = P0; s.setRand(rg); glv.mul, P2, P1, s.getMpz()); +} + +/* + lambda = 6 * z * z + mul (lambda * 2) = FrobeniusOnTwist * 2 +*/ +void testGLV2() +{ + G2 Q0, Q1, Q2; + mpz_class z = BN::param.z; + mpz_class r = BN::param.r; + mpz_class lambda = 6 * z * z; + mcl::bn::local::GLV2 glv2; + glv2.init(r, z, BN::param.isBLS12); + mpz_class n; + cybozu::XorShift rg; + mapToG2(Q0, 1); + for (int i = -10; i < 10; i++) { + n = i; + G2::mulGeneric(Q1, Q0, n); + glv2.mul(Q2, Q0, n); + CYBOZU_TEST_EQUAL(Q1, Q2); + } + for (int i = 1; i < 100; i++) { + mcl::gmp::getRand(n, glv2.rBitSize, rg); + n %= r; + n -= r/2; + mapToG2(Q0, i); + G2::mulGeneric(Q1, Q0, n); + glv2.mul(Q2, Q0, n); + CYBOZU_TEST_EQUAL(Q1, Q2); + } + Fr s; + mapToG2(Q0, 123); + CYBOZU_BENCH_C("G2::mul", 1000, Q2 = Q0; s.setRand(rg); G2::mulGeneric, Q2, Q1, s.getMpz()); + CYBOZU_BENCH_C("G2::glv", 1000, Q1 = Q0; s.setRand(rg); glv2.mul, Q2, Q1, s.getMpz()); +} + +CYBOZU_TEST_AUTO(glv) +{ + const mcl::CurveParam tbl[] = { + mcl::BN254, + mcl::BN381_1, + mcl::BN381_2, + mcl::BLS12_381, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const mcl::CurveParam& cp = tbl[i]; + initPairing(cp); + testGLV1(); + testGLV2(); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/gmp_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/gmp_test.cpp new file mode 100644 index 000000000..1fe9d4eb6 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/gmp_test.cpp @@ -0,0 +1,70 @@ +#include <mcl/gmp_util.hpp> +#include <vector> +#include <cybozu/test.hpp> + +CYBOZU_TEST_AUTO(testBit) +{ + const size_t maxBit = 100; + const size_t tbl[] = { + 3, 9, 5, 10, 50, maxBit + }; + mpz_class a; + std::vector<bool> b(maxBit + 1); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + a |= mpz_class(1) << tbl[i]; + b[tbl[i]] = 1; + } + for (size_t i = 0; i <= maxBit; i++) { + bool c1 = mcl::gmp::testBit(a, i); + bool c2 = b[i] != 0; + CYBOZU_TEST_EQUAL(c1, c2); + } +} + +CYBOZU_TEST_AUTO(getStr) +{ + const struct { + int x; + const char *dec; + const char *hex; + } tbl[] = { + { 0, "0", "0" }, + { 1, "1", "1" }, + { 10, "10", "a" }, + { 16, "16", "10" }, + { 123456789, "123456789", "75bcd15" }, + { -1, "-1", "-1" }, + { -10, "-10", "-a" }, + { -16, "-16", "-10" }, + { -100000000, "-100000000", "-5f5e100" }, + { -987654321, "-987654321", "-3ade68b1" }, + { -2147483647, "-2147483647", "-7fffffff" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + mpz_class x = tbl[i].x; + char buf[32]; + size_t n, len; + len = strlen(tbl[i].dec); + n = mcl::gmp::getStr(buf, len, x, 10); + CYBOZU_TEST_EQUAL(n, 0); + n = mcl::gmp::getStr(buf, len + 1, x, 10); + CYBOZU_TEST_EQUAL(n, len); + CYBOZU_TEST_EQUAL_ARRAY(buf, tbl[i].dec, n); + + len = strlen(tbl[i].hex); + n = mcl::gmp::getStr(buf, len, x, 16); + CYBOZU_TEST_EQUAL(n, 0); + n = mcl::gmp::getStr(buf, len + 1, x, 16); + CYBOZU_TEST_EQUAL(n, len); + CYBOZU_TEST_EQUAL_ARRAY(buf, tbl[i].hex, n); + } +} + +CYBOZU_TEST_AUTO(getRandPrime) +{ + for (int i = 0; i < 10; i++) { + mpz_class z; + mcl::gmp::getRandPrime(z, i * 10 + 3); + CYBOZU_TEST_ASSERT(mcl::gmp::isPrime(z)); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/low_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/low_test.cpp new file mode 100644 index 000000000..f5e72a0b3 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/low_test.cpp @@ -0,0 +1,73 @@ +#ifndef MCL_USE_LLVM + #define MCL_USE_LLVM +#endif +#include <cybozu/test.hpp> +#include <cybozu/xorshift.hpp> +#include <cybozu/itoa.hpp> +#include "../src/low_func.hpp" +#include <cybozu/benchmark.hpp> + +cybozu::XorShift rg; + +extern "C" void add_test(mcl::fp::Unit *z, const mcl::fp::Unit *x, const mcl::fp::Unit *y); + +template<size_t bit> +void bench() +{ + using namespace mcl::fp; + const size_t N = bit / UnitBitSize; + Unit x[N], y[N]; + for (int i = 0; i < 10; i++) { + Unit z[N]; + Unit w[N]; + rg.read(x, N); + rg.read(y, N); + AddPre<N, Gtag>::f(z, x, y); + AddPre<N, Ltag>::f(w, x, y); + CYBOZU_TEST_EQUAL_ARRAY(z, w, N); + + SubPre<N, Gtag>::f(z, x, y); + SubPre<N, Ltag>::f(w, x, y); + CYBOZU_TEST_EQUAL_ARRAY(z, w, N); + } + const std::string bitS = cybozu::itoa(bit); + std::string name; + name = "add" + bitS; CYBOZU_BENCH(name.c_str(), (AddPre<N, Ltag>::f), x, x, y); + name = "sub" + bitS; CYBOZU_BENCH(name.c_str(), (SubPre<N, Ltag>::f), x, x, y); +} + +CYBOZU_TEST_AUTO(addPre64) { bench<64>(); } +CYBOZU_TEST_AUTO(addPre128) { bench<128>(); } +CYBOZU_TEST_AUTO(addPre192) { bench<192>(); } +CYBOZU_TEST_AUTO(addPre256) { bench<256>(); } +CYBOZU_TEST_AUTO(addPre320) { bench<320>(); } +CYBOZU_TEST_AUTO(addPre384) { bench<384>(); } +CYBOZU_TEST_AUTO(addPre448) { bench<448>(); } +CYBOZU_TEST_AUTO(addPre512) { bench<512>(); } +//CYBOZU_TEST_AUTO(addPre96) { bench<96>(); } +//CYBOZU_TEST_AUTO(addPre160) { bench<160>(); } +//CYBOZU_TEST_AUTO(addPre224) { bench<224>(); } +#if 0 +CYBOZU_TEST_AUTO(addPre) +{ + using namespace mcl::fp; + const size_t bit = 128; + const size_t N = bit / UnitBitSize; + Unit x[N], y[N]; + for (int i = 0; i < 10; i++) { + Unit z[N]; + Unit w[N]; + rg.read(x, N); + rg.read(y, N); + low_addPre_G<N>(z, x, y); + addPre<bit>(w, x, y); + CYBOZU_TEST_EQUAL_ARRAY(z, w, N); + add_test(w, x, y); + CYBOZU_TEST_EQUAL_ARRAY(z, w, N); + } + std::string name = "add" + cybozu::itoa(bit); + CYBOZU_BENCH(name.c_str(), addPre<bit>, x, x, y); + CYBOZU_BENCH("add", add_test, x, x, y); +} +#endif + diff --git a/vendor/github.com/dexon-foundation/mcl/test/mk32.sh b/vendor/github.com/dexon-foundation/mcl/test/mk32.sh new file mode 100644 index 000000000..4d5f60711 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/mk32.sh @@ -0,0 +1 @@ +g++ -O3 -march=native base_test.cpp ../src/x86.s -m32 -I ~/32/include/ -I ../include/ -I ../../xbyak/ -I ../../cybozulib/include ~/32/lib/libgmp.a ~/32/lib/libgmpxx.a -I ~/32/lib -DNDEBUG diff --git a/vendor/github.com/dexon-foundation/mcl/test/modp_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/modp_test.cpp new file mode 100644 index 000000000..bf9da38bf --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/modp_test.cpp @@ -0,0 +1,37 @@ +#include <mcl/gmp_util.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/test.hpp> + +#define PUT(x) std::cout << #x << "=" << x << std::endl; + +CYBOZU_TEST_AUTO(modp) +{ + const int C = 1000000; + const char *pTbl[] = { + "0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", + "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", + }; + const char *xTbl[] = { + "0x12345678892082039482094823", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x10000000000000000000000000000000000000000000000000000000000000000", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + }; + mcl::Modp modp; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(pTbl); i++) { + const mpz_class p(pTbl[i]); + std::cout << std::hex << "p=" << p << std::endl; + modp.init(p); + for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(xTbl); j++) { + const mpz_class x(xTbl[j]); + std::cout << std::hex << "x=" << x << std::endl; + mpz_class r1, r2; + r1 = x % p; + modp.modp(r2, x); + CYBOZU_TEST_EQUAL(r1, r2); + CYBOZU_BENCH_C("x % p", C, mcl::gmp::mod, r1, x, p); + CYBOZU_BENCH_C("modp ", C, modp.modp, r2, x); + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/mont_fp_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/mont_fp_test.cpp new file mode 100644 index 000000000..e41e77a53 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/mont_fp_test.cpp @@ -0,0 +1,332 @@ +#define PUT(x) std::cout << #x "=" << (x) << std::endl +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/xorshift.hpp> +#include <time.h> + +#if 0 +#include <mcl/bls12_381.hpp> +using namespace mcl::bls12; +typedef Fr Zn; +#else +#include <mcl/fp.hpp> +struct ZnTag; +typedef mcl::FpT<ZnTag> Zn; +typedef mcl::FpT<> Fp; +#endif + +struct Montgomery { + typedef mcl::fp::Unit Unit; + mpz_class p_; + mpz_class R_; // (1 << (pn_ * 64)) % p + mpz_class RR_; // (R * R) % p + Unit rp_; // rp * p = -1 mod M = 1 << 64 + size_t pn_; + Montgomery() {} + explicit Montgomery(const mpz_class& p) + { + p_ = p; + rp_ = mcl::fp::getMontgomeryCoeff(mcl::gmp::getUnit(p, 0)); + pn_ = mcl::gmp::getUnitSize(p); + R_ = 1; + R_ = (R_ << (pn_ * 64)) % p_; + RR_ = (R_ * R_) % p_; + } + + void toMont(mpz_class& x) const { mul(x, x, RR_); } + void fromMont(mpz_class& x) const { mul(x, x, 1); } + + void mul(mpz_class& z, const mpz_class& x, const mpz_class& y) const + { +#if 0 + const size_t ySize = mcl::gmp::getUnitSize(y); + mpz_class c = x * mcl::gmp::getUnit(y, 0); + Unit q = mcl::gmp::getUnit(c, 0) * rp_; + c += p_ * q; + c >>= sizeof(Unit) * 8; + for (size_t i = 1; i < pn_; i++) { + if (i < ySize) { + c += x * mcl::gmp::getUnit(y, i); + } + Unit q = mcl::gmp::getUnit(c, 0) * rp_; + c += p_ * q; + c >>= sizeof(Unit) * 8; + } + if (c >= p_) { + c -= p_; + } + z = c; +#else + z = x * y; + for (size_t i = 0; i < pn_; i++) { + Unit q = mcl::gmp::getUnit(z, 0) * rp_; +#ifdef MCL_USE_VINT + z += p_ * q; +#else + mpz_class t; + mcl::gmp::set(t, q); + z += p_ * t; +#endif + z >>= sizeof(Unit) * 8; + } + if (z >= p_) { + z -= p_; + } +#endif + } + void mod(mpz_class& z, const mpz_class& xy) const + { + z = xy; + for (size_t i = 0; i < pn_; i++) { +//printf("i=%zd\n", i); +//std::cout << "z=" << std::hex << z << std::endl; + Unit q = mcl::gmp::getUnit(z, 0) * rp_; +//std::cout << "q=" << q << std::endl; + mpz_class t; + mcl::gmp::set(t, q); + z += p_ * t; + z >>= sizeof(Unit) * 8; +//std::cout << "z=" << std::hex << z << std::endl; + } + if (z >= p_) { + z -= p_; + } +//std::cout << "z=" << std::hex << z << std::endl; + } +}; + +template<class T> +mpz_class getMpz(const T& x) +{ + std::string str = x.getStr(); + mpz_class t; + mcl::gmp::setStr(t, str); + return t; +} + +template<class T> +std::string getStr(const T& x) +{ + std::ostringstream os; + os << x; + return os.str(); +} + +template<class T, class U> +T castTo(const U& x) +{ + T t; + t.setStr(getStr(x)); + return t; +} + +template<class T> +void putRaw(const T& x) +{ + const uint64_t *p = x.getInnerValue(); + for (size_t i = 0, n = T::BlockSize; i < n; i++) { + printf("%016llx", p[n - 1 - i]); + } + printf("\n"); +} + +template<size_t N> +void put(const uint64_t (&x)[N]) +{ + for (size_t i = 0; i < N; i++) { + printf("%016llx", x[N - 1 - i]); + } + printf("\n"); +} + +struct Test { + typedef mcl::FpT<> Fp; + void run(const char *p) + { + Fp::init(p); + Fp x("-123456789"); + Fp y("-0x7ffffffff"); + CYBOZU_BENCH("add", operator+, x, x); + CYBOZU_BENCH("sub", operator-, x, y); + CYBOZU_BENCH("mul", operator*, x, x); + CYBOZU_BENCH("sqr", Fp::sqr, x, x); + CYBOZU_BENCH("div", y += x; operator/, x, y); + } +}; + +void customTest(const char *pStr, const char *xStr, const char *yStr) +{ +#if 0 + { + pStr = "0xfffffffffffffffffffffffffffffffffffffffeffffee37", + Fp::init(pStr); + static uint64_t x[3] = { 1, 0, 0 }; + uint64_t z[3]; +std::cout<<std::hex; + Fp::inv(*(Fp*)z, *(const Fp*)x); +put(z); + exit(1); + } +#endif +#if 0 + std::cout << std::hex; + uint64_t x[9] = { 0xff7fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff }; + uint64_t y[9] = { 0xff7fffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff }; + uint64_t z1[9], z2[9]; + Fp::init(pStr); + Fp::fg_.mul_(z2, x, y); + put(z2); + { + puts("C"); + mpz_class p(pStr); + Montgomery mont(p); + mpz_class xx, yy; + mcl::gmp::setArray(xx, x, CYBOZU_NUM_OF_ARRAY(x)); + mcl::gmp::setArray(yy, y, CYBOZU_NUM_OF_ARRAY(y)); + mpz_class z; + mont.mul(z, xx, yy); + std::cout << std::hex << z << std::endl; + } + exit(1); +#else + std::string rOrg, rC, rAsm; + Zn::init(pStr); + Zn s(xStr), t(yStr); + s *= t; + rOrg = getStr(s); + { + puts("C"); + mpz_class p(pStr); + Montgomery mont(p); + mpz_class x(xStr), y(yStr); + mont.toMont(x); + mont.toMont(y); + mpz_class z; + mont.mul(z, x, y); + mont.fromMont(z); + rC = getStr(z); + } + + puts("asm"); + Fp::init(pStr); + Fp x(xStr), y(yStr); + x *= y; + rAsm = getStr(x); + CYBOZU_TEST_EQUAL(rOrg, rC); + CYBOZU_TEST_EQUAL(rOrg, rAsm); +#endif +} + +#if MCL_MAX_BIT_SIZE >= 521 +CYBOZU_TEST_AUTO(customTest) +{ + const struct { + const char *p; + const char *x; + const char *y; + } tbl[] = { + { + "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +// "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", +// "0xfffffffffffffffffffffffffffffffffffffffeffffee37", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + customTest(tbl[i].p, tbl[i].x, tbl[i].y); + } +} +#endif + +CYBOZU_TEST_AUTO(test) +{ + Test test; + const char *tbl[] = { +#if 1 + // N = 2 + "0x0000000000000001000000000000000d", + "0x7fffffffffffffffffffffffffffffff", + "0x8000000000000000000000000000001d", + "0xffffffffffffffffffffffffffffff61", + + // N = 3 + "0x000000000000000100000000000000000000000000000033", // min prime + "0x00000000fffffffffffffffffffffffffffffffeffffac73", + "0x0000000100000000000000000001b8fa16dfab9aca16b6b3", + "0x000000010000000000000000000000000000000000000007", + "0x30000000000000000000000000000000000000000000002b", + "0x70000000000000000000000000000000000000000000001f", + "0x800000000000000000000000000000000000000000000005", + "0xfffffffffffffffffffffffffffffffffffffffeffffee37", + "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", + "0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime + + // N = 4 + "0x0000000000000001000000000000000000000000000000000000000000000085", // min prime + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", + "0x7523648240000001ba344d80000000086121000000000013a700000000000017", + "0x800000000000000000000000000000000000000000000000000000000000005f", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime +#endif + +#if MCL_MAX_BIT_SIZE >= 384 + // N = 6 + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff", +#endif + +#if MCL_MAX_BIT_SIZE >= 521 + // N = 9 + "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + printf("prime=%s\n", tbl[i]); +#if 0 + mpz_class p(tbl[i]); + initPairing(mcl::BLS12_381); +#if 1 + cybozu::XorShift rg; + for (int i = 0; i < 1000; i++) { + Fp x, y, z; + FpDbl xy; + x.setByCSPRNG(rg); + y.setByCSPRNG(rg); + FpDbl::mulPre(xy, x, y); + FpDbl::mod(z, xy); + if (z != x * y) { + puts("ERR"); + std::cout << std::hex; + PUT(x); + PUT(y); + PUT(z); + PUT(x * y); + exit(1); + } + } +#else + Montgomery mont(p); + mpz_class x("19517141aafb2ffc39517141aafb2ffc39517141aafb2ffc39517141aafb2ffc39517141aafb2ffc39517141aafb2ffc", 16); + mpz_class y("139517141aafb2ffc39517141aafb2ffc39517141aafb2ffc39517141aafb2ffc39517141aafb2ffc39517141aafb2ff", 16); + std::cout << std::hex; + PUT(x); + PUT(y); + mpz_class z; + mont.mul(z, x, y); + PUT(z); + Fp x1, y1, z1; + puts("aaa"); + memcpy(&x1, mcl::gmp::getUnit(x), sizeof(x1)); + memcpy(&y1, mcl::gmp::getUnit(y), sizeof(y1)); + z1.clear(); + x1.dump(); + y1.dump(); + Fp::mul(z1, x1, y1); + z1.dump(); +#endif + exit(1); +#endif + test.run(tbl[i]); + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/paillier_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/paillier_test.cpp new file mode 100644 index 000000000..31d2b26fc --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/paillier_test.cpp @@ -0,0 +1,24 @@ +#include <cybozu/test.hpp> +#include <mcl/paillier.hpp> + +CYBOZU_TEST_AUTO(paillier) +{ + using namespace mcl::paillier; + SecretKey sec; + sec.init(2048); + PublicKey pub; + sec.getPublicKey(pub); + mpz_class m1("12342340928409"), m2("23049820498204"); + mpz_class c1, c2, c3; + pub.enc(c1, m1); + pub.enc(c2, m2); + std::cout << std::hex << "c1=" << c1 << "\nc2=" << c2 << std::endl; + pub.add(c3, c1, c2); + mpz_class d1, d2, d3; + sec.dec(d1, c1); + sec.dec(d2, c2); + sec.dec(d3, c3); + CYBOZU_TEST_EQUAL(m1, d1); + CYBOZU_TEST_EQUAL(m2, d2); + CYBOZU_TEST_EQUAL(m1 + m2, d3); +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/proj/bn_test/bn_test.vcxproj b/vendor/github.com/dexon-foundation/mcl/test/proj/bn_test/bn_test.vcxproj new file mode 100644 index 000000000..936e075aa --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/proj/bn_test/bn_test.vcxproj @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9F935350-2F4C-45FA-A1C2-1D5AA0EADC96}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>bn_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)debug.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)release.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="$(SolutionDir)test\\bn_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/mcl/test/proj/ec_test/ec_test.vcxproj b/vendor/github.com/dexon-foundation/mcl/test/proj/ec_test/ec_test.vcxproj new file mode 100644 index 000000000..4bdfda2cb --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/proj/ec_test/ec_test.vcxproj @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{46B6E88E-739A-406B-9F68-BC46C5950FA3}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>ec_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)debug.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)release.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="$(SolutionDir)test\ec_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/vendor/github.com/dexon-foundation/mcl/test/proj/fp_test/fp_test.vcxproj b/vendor/github.com/dexon-foundation/mcl/test/proj/fp_test/fp_test.vcxproj new file mode 100644 index 000000000..f705982bf --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/proj/fp_test/fp_test.vcxproj @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{51266DE6-B57B-4AE3-B85C-282F170E1728}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>fp_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)debug.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)release.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="$(SolutionDir)test\\fp_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/mcl/test/proj/fp_tower_test/fp_tower_test.vcxproj b/vendor/github.com/dexon-foundation/mcl/test/proj/fp_tower_test/fp_tower_test.vcxproj new file mode 100644 index 000000000..d5720678f --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/proj/fp_tower_test/fp_tower_test.vcxproj @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{733B6250-D249-4A99-B2A6-C8FAF6A90E97}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>fp_tower_test</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)debug.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)common.props" /> + <Import Project="$(SolutionDir)release.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="$(SolutionDir)test\\fp_tower_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/vendor/github.com/dexon-foundation/mcl/test/she_c256_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/she_c256_test.cpp new file mode 100644 index 000000000..3e458b623 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/she_c256_test.cpp @@ -0,0 +1,2 @@ +#define MCLBN_FP_UNIT_SIZE 4 +#include "she_c_test.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/test/she_c384_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/she_c384_test.cpp new file mode 100644 index 000000000..5c7bd9882 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/she_c384_test.cpp @@ -0,0 +1,2 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#include "she_c_test.hpp" diff --git a/vendor/github.com/dexon-foundation/mcl/test/she_c_test.hpp b/vendor/github.com/dexon-foundation/mcl/test/she_c_test.hpp new file mode 100644 index 000000000..8287c0e0a --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/she_c_test.hpp @@ -0,0 +1,535 @@ +#include <mcl/she.h> +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/test.hpp> +#include <cybozu/option.hpp> +#include <fstream> + +const size_t hashSize = 1 << 10; +const size_t tryNum = 1024; + +CYBOZU_TEST_AUTO(init) +{ + int curve; +#if MCLBN_FP_UNIT_SIZE == 4 + curve = MCL_BN254; +#elif MCLBN_FP_UNIT_SIZE == 6 +// curve = MCL_BN381_1; + curve = MCL_BLS12_381; +#elif MCLBN_FP_UNIT_SIZE == 8 + curve = MCL_BN462; +#endif + int ret; + ret = sheInit(curve, MCLBN_COMPILED_TIME_VAR); + CYBOZU_TEST_EQUAL(ret, 0); + ret = sheSetRangeForDLP(hashSize); + CYBOZU_TEST_EQUAL(ret, 0); +} + +CYBOZU_TEST_AUTO(encDec) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m = 123; + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheCipherTextGT ct; + sheEncG1(&c1, &pub, m); + sheEncG2(&c2, &pub, m); + sheEncGT(&ct, &pub, m); + + int64_t dec; + CYBOZU_TEST_EQUAL(sheDecG1(&dec, &sec, &c1), 0); + CYBOZU_TEST_EQUAL(dec, m); + dec = 0; + CYBOZU_TEST_EQUAL(sheDecG1ViaGT(&dec, &sec, &c1), 0); + CYBOZU_TEST_EQUAL(dec, m); + dec = 0; + CYBOZU_TEST_EQUAL(sheDecG2(&dec, &sec, &c2), 0); + CYBOZU_TEST_EQUAL(dec, m); + dec = 0; + CYBOZU_TEST_EQUAL(sheDecG2ViaGT(&dec, &sec, &c2), 0); + CYBOZU_TEST_EQUAL(dec, m); + dec = 0; + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, m); + + for (int m = -3; m < 3; m++) { + sheEncG1(&c1, &pub, m); + CYBOZU_TEST_EQUAL(sheIsZeroG1(&sec, &c1), m == 0); + sheEncG2(&c2, &pub, m); + CYBOZU_TEST_EQUAL(sheIsZeroG2(&sec, &c2), m == 0); + sheEncGT(&ct, &pub, m); + CYBOZU_TEST_EQUAL(sheIsZeroGT(&sec, &ct), m == 0); + } +} + +CYBOZU_TEST_AUTO(addMul) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m1 = 12; + int64_t m2 = -9; + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheCipherTextGT ct; + sheEncG1(&c1, &pub, m1); + sheEncG2(&c2, &pub, m2); + sheMul(&ct, &c1, &c2); + + int64_t dec; + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, m1 * m2); +} + +CYBOZU_TEST_AUTO(allOp) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m1 = 12; + int64_t m2 = -9; + int64_t m3 = 12; + int64_t m4 = -9; + int64_t dec; + sheCipherTextG1 c11, c12; + sheCipherTextG2 c21, c22; + sheCipherTextGT ct; + + sheEncG1(&c11, &pub, m1); + sheNegG1(&c12, &c11); + CYBOZU_TEST_EQUAL(sheDecG1(&dec, &sec, &c12), 0); + CYBOZU_TEST_EQUAL(dec, -m1); + + sheEncG1(&c12, &pub, m2); + sheSubG1(&c11, &c11, &c12); // m1 - m2 + sheMulG1(&c11, &c11, 4); // 4 * (m1 - m2) + + sheEncG2(&c21, &pub, m3); + sheNegG2(&c22, &c21); + CYBOZU_TEST_EQUAL(sheDecG2(&dec, &sec, &c22), 0); + CYBOZU_TEST_EQUAL(dec, -m3); + sheEncG2(&c22, &pub, m4); + sheSubG2(&c21, &c21, &c22); // m3 - m4 + sheMulG2(&c21, &c21, -5); // -5 * (m3 - m4) + sheMul(&ct, &c11, &c21); // -20 * (m1 - m2) * (m3 - m4) + sheAddGT(&ct, &ct, &ct); // -40 * (m1 - m2) * (m3 - m4) + sheMulGT(&ct, &ct, -4); // 160 * (m1 - m2) * (m3 - m4) + + int64_t t = 160 * (m1 - m2) * (m3 - m4); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, t); + + sheCipherTextGT ct2; + sheNegGT(&ct2, &ct); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct2), 0); + CYBOZU_TEST_EQUAL(dec, -t); +} + +CYBOZU_TEST_AUTO(rerand) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m1 = 12; + int64_t m2 = -9; + int64_t m3 = 12; + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheCipherTextGT ct1, ct2; + sheEncG1(&c1, &pub, m1); + sheReRandG1(&c1, &pub); + + sheEncG2(&c2, &pub, m2); + sheReRandG2(&c2, &pub); + + sheEncGT(&ct1, &pub, m3); + sheReRandGT(&ct1, &pub); + + sheMul(&ct2, &c1, &c2); + sheReRandGT(&ct2, &pub); + sheAddGT(&ct1, &ct1, &ct2); + + int64_t dec; + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct1), 0); + CYBOZU_TEST_EQUAL(dec, m1 * m2 + m3); +} + +CYBOZU_TEST_AUTO(serialize) +{ + sheSecretKey sec1, sec2; + sheSecretKeySetByCSPRNG(&sec1); + shePublicKey pub1, pub2; + sheGetPublicKey(&pub1, &sec1); + + char buf1[4096], buf2[4096]; + size_t n1, n2; + size_t r, size; + const size_t sizeofFr = mclBn_getFrByteSize(); + const size_t sizeofFp = mclBn_getG1ByteSize(); + + size = sizeofFr * 2; + n1 = sheSecretKeySerialize(buf1, sizeof(buf1), &sec1); + CYBOZU_TEST_EQUAL(n1, size); + r = sheSecretKeyDeserialize(&sec2, buf1, n1); + CYBOZU_TEST_EQUAL(r, n1); + n2 = sheSecretKeySerialize(buf2, sizeof(buf2), &sec2); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + size = sizeofFp * 3; + n1 = shePublicKeySerialize(buf1, sizeof(buf1), &pub1); + CYBOZU_TEST_EQUAL(n1, size); + r = shePublicKeyDeserialize(&pub2, buf1, n1); + CYBOZU_TEST_EQUAL(r, n1); + n2 = shePublicKeySerialize(buf2, sizeof(buf2), &pub2); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + int m = 123; + sheCipherTextG1 c11, c12; + sheCipherTextG2 c21, c22; + sheCipherTextGT ct1, ct2; + sheEncG1(&c11, &pub2, m); + sheEncG2(&c21, &pub2, m); + sheEncGT(&ct1, &pub2, m); + + size = sizeofFp * 2; + n1 = sheCipherTextG1Serialize(buf1, sizeof(buf1), &c11); + CYBOZU_TEST_EQUAL(n1, size); + r = sheCipherTextG1Deserialize(&c12, buf1, n1); + CYBOZU_TEST_EQUAL(r, n1); + n2 = sheCipherTextG1Serialize(buf2, sizeof(buf2), &c12); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + size = sizeofFp * 4; + n1 = sheCipherTextG2Serialize(buf1, sizeof(buf1), &c21); + CYBOZU_TEST_EQUAL(n1, size); + r = sheCipherTextG2Deserialize(&c22, buf1, n1); + CYBOZU_TEST_EQUAL(r, n1); + n2 = sheCipherTextG2Serialize(buf2, sizeof(buf2), &c22); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + size = sizeofFp * 12 * 4; + n1 = sheCipherTextGTSerialize(buf1, sizeof(buf1), &ct1); + CYBOZU_TEST_EQUAL(n1, size); + r = sheCipherTextGTDeserialize(&ct2, buf1, n1); + CYBOZU_TEST_EQUAL(r, n1); + n2 = sheCipherTextGTSerialize(buf2, sizeof(buf2), &ct2); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); +} + +CYBOZU_TEST_AUTO(convert) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + sheCipherTextGT ct; + const int64_t m = 123; + int64_t dec; + sheCipherTextG1 c1; + sheEncG1(&c1, &pub, m); + CYBOZU_TEST_EQUAL(sheDecG1(&dec, &sec, &c1), 0); + CYBOZU_TEST_EQUAL(dec, 123); + sheConvertG1(&ct, &pub, &c1); + dec = 0; + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, 123); + + sheCipherTextG2 c2; + sheEncG2(&c2, &pub, m); + CYBOZU_TEST_EQUAL(sheDecG2(&dec, &sec, &c2), 0); + CYBOZU_TEST_EQUAL(dec, 123); + sheConvertG2(&ct, &pub, &c2); + dec = 0; + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, 123); +} + +CYBOZU_TEST_AUTO(precomputed) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + shePrecomputedPublicKey *ppub = shePrecomputedPublicKeyCreate(); + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyInit(ppub, &pub), 0); + const int64_t m = 152; + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheCipherTextGT ct; + int64_t dec = 0; + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyEncG1(&c1, ppub, m), 0); + CYBOZU_TEST_EQUAL(sheDecG1(&dec, &sec, &c1), 0); + CYBOZU_TEST_EQUAL(dec, m); + dec = 0; + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyEncG2(&c2, ppub, m), 0); + CYBOZU_TEST_EQUAL(sheDecG2(&dec, &sec, &c2), 0); + CYBOZU_TEST_EQUAL(dec, m); + dec = 0; + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyEncGT(&ct, ppub, m), 0); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, m); + + shePrecomputedPublicKeyDestroy(ppub); +} + +template<class CT, class PK, class encWithZkpFunc, class decFunc, class verifyFunc> +void ZkpBinTest(const sheSecretKey *sec, const PK *pub, encWithZkpFunc encWithZkp, decFunc dec, verifyFunc verify) +{ + CT c; + sheZkpBin zkp; + for (int m = 0; m < 2; m++) { + CYBOZU_TEST_EQUAL(encWithZkp(&c, &zkp, pub, m), 0); + mclInt mDec; + CYBOZU_TEST_EQUAL(dec(&mDec, sec, &c), 0); + CYBOZU_TEST_EQUAL(mDec, m); + CYBOZU_TEST_EQUAL(verify(pub, &c, &zkp), 1); + { + char buf[4096]; + size_t n = sheZkpBinSerialize(buf, sizeof(buf), &zkp); + CYBOZU_TEST_EQUAL(n, mclBn_getFrByteSize() * CYBOZU_NUM_OF_ARRAY(zkp.d)); + sheZkpBin zkp2; + size_t r = sheZkpBinDeserialize(&zkp2, buf, n); + CYBOZU_TEST_EQUAL(r, n); + CYBOZU_TEST_EQUAL(r, n); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(zkp.d); i++) { + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&zkp.d[i], &zkp2.d[i])); + } + } + zkp.d[0].d[0]++; + CYBOZU_TEST_EQUAL(verify(pub, &c, &zkp), 0); + } + CYBOZU_TEST_ASSERT(encWithZkp(&c, &zkp, pub, 2) != 0); +} + +CYBOZU_TEST_AUTO(ZkpBin) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + ZkpBinTest<sheCipherTextG1>(&sec, &pub, sheEncWithZkpBinG1, sheDecG1, sheVerifyZkpBinG1); + ZkpBinTest<sheCipherTextG2>(&sec, &pub, sheEncWithZkpBinG2, sheDecG2, sheVerifyZkpBinG2); + + shePrecomputedPublicKey *ppub = shePrecomputedPublicKeyCreate(); + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyInit(ppub, &pub), 0); + + ZkpBinTest<sheCipherTextG1>(&sec, ppub, shePrecomputedPublicKeyEncWithZkpBinG1, sheDecG1, shePrecomputedPublicKeyVerifyZkpBinG1); + ZkpBinTest<sheCipherTextG2>(&sec, ppub, shePrecomputedPublicKeyEncWithZkpBinG2, sheDecG2, shePrecomputedPublicKeyVerifyZkpBinG2); + + shePrecomputedPublicKeyDestroy(ppub); +} + +template<class PK, class encWithZkpFunc, class verifyFunc> +void ZkpBinEqTest(const sheSecretKey *sec, const PK *pub, encWithZkpFunc encWithZkp, verifyFunc verify) +{ + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheZkpBinEq zkp; + for (int m = 0; m < 2; m++) { + CYBOZU_TEST_EQUAL(encWithZkp(&c1, &c2, &zkp, pub, m), 0); + mclInt mDec = -1; + CYBOZU_TEST_EQUAL(sheDecG1(&mDec, sec, &c1), 0); + CYBOZU_TEST_EQUAL(mDec, m); + mDec = -1; + CYBOZU_TEST_EQUAL(sheDecG2(&mDec, sec, &c2), 0); + CYBOZU_TEST_EQUAL(mDec, m); + CYBOZU_TEST_EQUAL(verify(pub, &c1, &c2, &zkp), 1); + { + char buf[2048]; + size_t n = sheZkpBinEqSerialize(buf, sizeof(buf), &zkp); + CYBOZU_TEST_EQUAL(n, mclBn_getFrByteSize() * CYBOZU_NUM_OF_ARRAY(zkp.d)); + sheZkpBinEq zkp2; + size_t r = sheZkpBinEqDeserialize(&zkp2, buf, n); + CYBOZU_TEST_EQUAL(r, n); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(zkp.d); i++) { + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&zkp.d[i], &zkp2.d[i])); + } + } + zkp.d[0].d[0]++; + CYBOZU_TEST_EQUAL(verify(pub, &c1, &c2, &zkp), 0); + } + CYBOZU_TEST_ASSERT(encWithZkp(&c1, &c2, &zkp, pub, 2) != 0); +} + +CYBOZU_TEST_AUTO(ZkpBinEq) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + ZkpBinEqTest(&sec, &pub, sheEncWithZkpBinEq, sheVerifyZkpBinEq); + + shePrecomputedPublicKey *ppub = shePrecomputedPublicKeyCreate(); + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyInit(ppub, &pub), 0); + + ZkpBinEqTest(&sec, ppub, shePrecomputedPublicKeyEncWithZkpBinEq, shePrecomputedPublicKeyVerifyZkpBinEq); + + shePrecomputedPublicKeyDestroy(ppub); +} + +template<class PK, class encWithZkpFunc, class verifyFunc> +void ZkpEqTest(const sheSecretKey *sec, const PK *pub, encWithZkpFunc encWithZkp, verifyFunc verify) +{ + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheZkpEq zkp; + for (int m = -5; m < 5; m++) { + CYBOZU_TEST_EQUAL(encWithZkp(&c1, &c2, &zkp, pub, m), 0); + mclInt mDec = -1; + CYBOZU_TEST_EQUAL(sheDecG1(&mDec, sec, &c1), 0); + CYBOZU_TEST_EQUAL(mDec, m); + mDec = -1; + CYBOZU_TEST_EQUAL(sheDecG2(&mDec, sec, &c2), 0); + CYBOZU_TEST_EQUAL(mDec, m); + CYBOZU_TEST_EQUAL(verify(pub, &c1, &c2, &zkp), 1); + { + char buf[2048]; + size_t n = sheZkpEqSerialize(buf, sizeof(buf), &zkp); + CYBOZU_TEST_EQUAL(n, mclBn_getFrByteSize() * CYBOZU_NUM_OF_ARRAY(zkp.d)); + sheZkpEq zkp2; + size_t r = sheZkpEqDeserialize(&zkp2, buf, n); + CYBOZU_TEST_EQUAL(r, n); + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(zkp.d); i++) { + CYBOZU_TEST_ASSERT(mclBnFr_isEqual(&zkp.d[i], &zkp2.d[i])); + } + } + zkp.d[0].d[0]++; + CYBOZU_TEST_EQUAL(verify(pub, &c1, &c2, &zkp), 0); + } +} + +CYBOZU_TEST_AUTO(ZkpEq) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + ZkpEqTest(&sec, &pub, sheEncWithZkpEq, sheVerifyZkpEq); + + shePrecomputedPublicKey *ppub = shePrecomputedPublicKeyCreate(); + CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyInit(ppub, &pub), 0); + + ZkpEqTest(&sec, ppub, shePrecomputedPublicKeyEncWithZkpEq, shePrecomputedPublicKeyVerifyZkpEq); + + shePrecomputedPublicKeyDestroy(ppub); +} + +CYBOZU_TEST_AUTO(finalExp) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + const int64_t m11 = 5; + const int64_t m12 = 7; + const int64_t m21 = -3; + const int64_t m22 = 9; + sheCipherTextG1 c11, c12; + sheCipherTextG2 c21, c22; + sheCipherTextGT ct1, ct2; + sheCipherTextGT ct; + sheEncG1(&c11, &pub, m11); + sheEncG1(&c12, &pub, m12); + sheEncG2(&c21, &pub, m21); + sheEncG2(&c22, &pub, m22); + + int64_t dec; + // sheMul = sheMulML + sheFinalExpGT + sheMul(&ct1, &c11, &c21); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct1), 0); + CYBOZU_TEST_EQUAL(dec, m11 * m21); + + sheMulML(&ct1, &c11, &c21); + sheFinalExpGT(&ct, &ct1); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, m11 * m21); + + sheMulML(&ct2, &c12, &c22); + sheFinalExpGT(&ct, &ct2); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, m12 * m22); + + /* + Mul(c11, c21) + Mul(c21, c22) + = finalExp(ML(c11, c21) + ML(c21, c22)) + */ + sheAddGT(&ct, &ct1, &ct2); + sheFinalExpGT(&ct, &ct); + CYBOZU_TEST_EQUAL(sheDecGT(&dec, &sec, &ct), 0); + CYBOZU_TEST_EQUAL(dec, (m11 * m21) + (m12 * m22)); +} + +int g_hashBitSize = 8; +std::string g_tableName; + +CYBOZU_TEST_AUTO(saveLoad) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + const size_t hashSize = 1 << g_hashBitSize; + const size_t byteSizePerEntry = 8; + sheSetRangeForGTDLP(hashSize); + std::string buf; + buf.resize(hashSize * byteSizePerEntry + 1024); + const size_t n1 = sheSaveTableForGTDLP(&buf[0], buf.size()); + CYBOZU_TEST_ASSERT(n1 > 0); + if (!g_tableName.empty()) { + printf("use table=%s\n", g_tableName.c_str()); + std::ofstream ofs(g_tableName.c_str(), std::ios::binary); + ofs.write(buf.c_str(), n1); + } + const int64_t m = hashSize - 1; + sheCipherTextGT ct; + CYBOZU_TEST_ASSERT(sheEncGT(&ct, &pub, m) == 0); + sheSetRangeForGTDLP(1); + sheSetTryNum(1); + int64_t dec = 0; + CYBOZU_TEST_ASSERT(sheDecGT(&dec, &sec, &ct) != 0); + if (!g_tableName.empty()) { + std::ifstream ifs(g_tableName.c_str(), std::ios::binary); + buf.clear(); + buf.resize(n1); + ifs.read(&buf[0], n1); + } + const size_t n2 = sheLoadTableForGTDLP(&buf[0], n1); + CYBOZU_TEST_ASSERT(n2 > 0); + CYBOZU_TEST_ASSERT(sheDecGT(&dec, &sec, &ct) == 0); + CYBOZU_TEST_EQUAL(dec, m); +} + +int main(int argc, char *argv[]) + try +{ + cybozu::Option opt; + opt.appendOpt(&g_hashBitSize, 8, "bit", ": hashBitSize"); + opt.appendOpt(&g_tableName, "", "f", ": table name"); + opt.appendHelp("h", ": show this message"); + if (!opt.parse(argc, argv)) { + opt.usage(); + return 1; + } + return cybozu::test::autoRun.run(argc, argv); +} catch (std::exception& e) { + printf("ERR %s\n", e.what()); + return 1; +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/she_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/she_test.cpp new file mode 100644 index 000000000..9292c35f4 --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/she_test.cpp @@ -0,0 +1,756 @@ +#define PUT(x) std::cout << #x << "=" << (x) << std::endl; +#include <cybozu/test.hpp> +#include <cybozu/benchmark.hpp> +#include <cybozu/xorshift.hpp> +#include <fstream> +#include <time.h> +#include <mcl/she.hpp> +#include <mcl/ecparam.hpp> // for secp192k1 + +using namespace mcl::she; + +SecretKey g_sec; + +CYBOZU_TEST_AUTO(log) +{ +#if MCLBN_FP_UNIT_SIZE == 4 + const mcl::CurveParam& cp = mcl::BN254; + puts("BN254"); +#elif MCLBN_FP_UNIT_SIZE == 6 + const mcl::CurveParam& cp = mcl::BN381_1; + puts("BN381_1"); +#elif MCLBN_FP_UNIT_SIZE == 8 + const mcl::CurveParam& cp = mcl::BN462; + puts("BN462"); +#endif + init(cp); + G1 P; + hashAndMapToG1(P, "abc"); + for (int i = -5; i < 5; i++) { + G1 iP; + G1::mul(iP, P, i); + CYBOZU_TEST_EQUAL(mcl::she::local::log(P, iP), i); + } +} + +//#define PAPER +#ifdef PAPER +double clk2msec(const cybozu::CpuClock& clk, int n) +{ + const double rate = (1 / 3.4e9) * 1.e3; // 3.4GHz + return clk.getClock() / (double)clk.getCount() / n * rate; +} + +CYBOZU_TEST_AUTO(bench2) +{ + puts("msec"); + setTryNum(1 << 16); + useDecG1ViaGT(true); + useDecG2ViaGT(true); +#if 0 + setRangeForDLP(1 << 21); +#else + { + const char *tblName = "../she-dlp-table/she-dlp-0-20-gt.bin"; + std::ifstream ifs(tblName, std::ios::binary); + getHashTableGT().load(ifs); + } +#endif + SecretKey sec; + sec.setByCSPRNG(); + PublicKey pub; + sec.getPublicKey(pub); + PrecomputedPublicKey ppub; + ppub.init(pub); + const int C = 500; + double t1, t2; + int64_t m = (1ll << 31) - 12345; + CipherTextG1 c1, d1; + CipherTextG2 c2, d2; + CipherTextGT ct, dt; + CYBOZU_BENCH_C("", C, ppub.enc, c1, m); + t1 = clk2msec(cybozu::bench::g_clk, C); + CYBOZU_TEST_EQUAL(sec.dec(c1), m); + + CYBOZU_BENCH_C("", C, ppub.enc, c2, m); + t2 = clk2msec(cybozu::bench::g_clk, C); + CYBOZU_TEST_EQUAL(sec.dec(c2), m); + printf("Enc G1 %.2e\n", t1); + printf("Enc G2 %.2e\n", t2); + printf("Enc L1(G1+G2) %.2e\n", t1 + t2); + + CYBOZU_BENCH_C("", C, ppub.enc, ct, m); + t1 = clk2msec(cybozu::bench::g_clk, C); + CYBOZU_TEST_EQUAL(sec.dec(ct), m); + printf("Enc L2 %.2e\n", t1); + + CYBOZU_BENCH_C("", C, sec.dec, c1); + t1 = clk2msec(cybozu::bench::g_clk, C); + printf("Dec L1 %.2e\n", t1); + + CYBOZU_BENCH_C("", C, sec.dec, ct); + t1 = clk2msec(cybozu::bench::g_clk, C); + printf("Dec L2 %.2e\n", t1); + + pub.enc(ct, 1234); + CYBOZU_BENCH_C("", C, sec.dec, ct); + t1 = clk2msec(cybozu::bench::g_clk, C); + printf("Dec L2(small) %.2e\n", t1); + + CYBOZU_BENCH_C("", C, add, d1, d1, c1); + t1 = clk2msec(cybozu::bench::g_clk, C); + + CYBOZU_BENCH_C("", C, add, d2, d2, c2); + t2 = clk2msec(cybozu::bench::g_clk, C); + printf("Add G1 %.2e\n", t1); + printf("Add G2 %.2e\n", t2); + printf("Add L1(G1+G2) %.2e\n", t1 + t2); + + CYBOZU_BENCH_C("", C, add, dt, dt, ct); + t1 = clk2msec(cybozu::bench::g_clk, C); + printf("Add L2 %.2e\n", t1); + + CYBOZU_BENCH_C("", C, mul, ct, c1, c2); + t1 = clk2msec(cybozu::bench::g_clk, C); + printf("Mul %.2e\n", t1); + + CYBOZU_BENCH_C("", C, ppub.reRand, c1); + t1 = clk2msec(cybozu::bench::g_clk, C); + CYBOZU_BENCH_C("", C, ppub.reRand, c2); + t2 = clk2msec(cybozu::bench::g_clk, C); + printf("ReRand G1 %.2e\n", t1); + printf("ReRand G2 %.2e\n", t2); + printf("ReRand L1(G1+G2) %.2e\n", t1 + t2); + + CYBOZU_BENCH_C("", C, ppub.reRand, ct); + t1 = clk2msec(cybozu::bench::g_clk, C); + printf("ReRand L2 %.2e\n", t1); +} +#endif + +template<class G, class HashTbl> +void GAHashTableTest(int maxSize, int tryNum, const G& P, const HashTbl& hashTbl) +{ + for (int i = -maxSize; i <= maxSize; i++) { + G xP; + G::mul(xP, P, i); + CYBOZU_TEST_EQUAL(hashTbl.basicLog(xP), i); + } + for (int i = -maxSize * tryNum; i <= maxSize * tryNum; i++) { + G xP; + G::mul(xP, P, i); + CYBOZU_TEST_EQUAL(hashTbl.log(xP), i); + } +} + +template<class G> +void HashTableTest(const G& P) +{ + mcl::she::local::HashTable<G> hashTbl, hashTbl2; + const int maxSize = 100; + const int tryNum = 3; + hashTbl.init(P, maxSize, tryNum); + GAHashTableTest(maxSize, tryNum, P, hashTbl); + std::stringstream ss; + hashTbl.save(ss); + hashTbl2.load(ss); + GAHashTableTest(maxSize, tryNum, P, hashTbl2); +} + +CYBOZU_TEST_AUTO(HashTable) +{ + G1 P; + hashAndMapToG1(P, "abc"); + G2 Q; + hashAndMapToG2(Q, "abc"); + HashTableTest(P); + HashTableTest(Q); +} + +template<class HashTbl> +void GTHashTableTest(int maxSize, int tryNum, const GT& g, const HashTbl& hashTbl) +{ + for (int i = -maxSize; i <= maxSize; i++) { + GT gx; + GT::pow(gx, g, i); + CYBOZU_TEST_EQUAL(hashTbl.basicLog(gx), i); + } + for (int i = -maxSize * tryNum; i <= maxSize * tryNum; i++) { + GT gx; + GT::pow(gx, g, i); + CYBOZU_TEST_EQUAL(hashTbl.log(gx), i); + } +} + +CYBOZU_TEST_AUTO(GTHashTable) +{ + mcl::she::local::HashTable<GT, false> hashTbl, hashTbl2; + GT g; + { + G1 P; + hashAndMapToG1(P, "abc"); + G2 Q; + hashAndMapToG2(Q, "abc"); + pairing(g, P, Q); + } + const int maxSize = 100; + const int tryNum = 3; + hashTbl.init(g, maxSize, tryNum); + GTHashTableTest(maxSize, tryNum, g, hashTbl); + std::stringstream ss; + hashTbl.save(ss); + hashTbl2.load(ss); + GTHashTableTest(maxSize, tryNum, g, hashTbl2); +} + +CYBOZU_TEST_AUTO(enc_dec) +{ + SecretKey& sec = g_sec; + sec.setByCSPRNG(); + setRangeForDLP(1024); + PublicKey pub; + sec.getPublicKey(pub); + CipherText c; + for (int i = -5; i < 5; i++) { + pub.enc(c, i); + CYBOZU_TEST_EQUAL(sec.dec(c), i); + pub.reRand(c); + CYBOZU_TEST_EQUAL(sec.dec(c), i); + } + PrecomputedPublicKey ppub; + ppub.init(pub); + CipherTextG1 c1; + CipherTextG2 c2; + CipherTextGT ct1, ct2; + for (int i = -5; i < 5; i++) { + pub.enc(ct1, i); + CYBOZU_TEST_EQUAL(sec.dec(ct1), i); + CYBOZU_TEST_EQUAL(sec.isZero(ct1), i == 0); + ppub.enc(ct2, i); + CYBOZU_TEST_EQUAL(sec.dec(ct2), i); + ppub.enc(c1, i); + CYBOZU_TEST_EQUAL(sec.dec(c1), i); + CYBOZU_TEST_EQUAL(sec.decViaGT(c1), i); + CYBOZU_TEST_EQUAL(sec.isZero(c1), i == 0); + ct1.clear(); + pub.convert(ct1, c1); + CYBOZU_TEST_EQUAL(sec.dec(ct1), i); + ppub.enc(c2, i); + CYBOZU_TEST_EQUAL(sec.dec(c2), i); + CYBOZU_TEST_EQUAL(sec.decViaGT(c2), i); + CYBOZU_TEST_EQUAL(sec.isZero(c2), i == 0); + ct1.clear(); + pub.convert(ct1, c2); + CYBOZU_TEST_EQUAL(sec.dec(ct1), i); + pub.enc(c, i); + CYBOZU_TEST_EQUAL(sec.isZero(c), i == 0); + } +} + +template<class CT, class PK> +void ZkpBinTest(const SecretKey& sec, const PK& pub) +{ + CT c; + ZkpBin zkp; + for (int m = 0; m < 2; m++) { + pub.encWithZkpBin(c, zkp, m); + CYBOZU_TEST_EQUAL(sec.dec(c), m); + CYBOZU_TEST_ASSERT(pub.verify(c, zkp)); + zkp.d_[0] += 1; + CYBOZU_TEST_ASSERT(!pub.verify(c, zkp)); + } + CYBOZU_TEST_EXCEPTION(pub.encWithZkpBin(c, zkp, 2), cybozu::Exception); +} +CYBOZU_TEST_AUTO(ZkpBin) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + ZkpBinTest<CipherTextG1>(sec, pub); + ZkpBinTest<CipherTextG2>(sec, pub); + + PrecomputedPublicKey ppub; + ppub.init(pub); + ZkpBinTest<CipherTextG1>(sec, ppub); + ZkpBinTest<CipherTextG2>(sec, ppub); +} + +template<class PubT> +void ZkpEqTest(const SecretKey& sec, const PubT& pub) +{ + CipherTextG1 c1; + CipherTextG2 c2; + ZkpEq zkp; + for (int m = -4; m < 4; m++) { + pub.encWithZkpEq(c1, c2, zkp, m); + CYBOZU_TEST_EQUAL(sec.dec(c1), m); + CYBOZU_TEST_EQUAL(sec.dec(c2), m); + CYBOZU_TEST_ASSERT(pub.verify(c1, c2, zkp)); + zkp.d_[0] += 1; + CYBOZU_TEST_ASSERT(!pub.verify(c1, c2, zkp)); + } +} + +CYBOZU_TEST_AUTO(ZkpEq) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + PrecomputedPublicKey ppub; + ppub.init(pub); + ZkpEqTest(sec, pub); + ZkpEqTest(sec, ppub); +} + +template<class PK> +void ZkpBinEqTest(const SecretKey& sec, const PK& pub) +{ + CipherTextG1 c1; + CipherTextG2 c2; + ZkpBinEq zkp; + for (int m = 0; m < 2; m++) { + pub.encWithZkpBinEq(c1, c2, zkp, m); + CYBOZU_TEST_EQUAL(sec.dec(c1), m); + CYBOZU_TEST_EQUAL(sec.dec(c2), m); + CYBOZU_TEST_ASSERT(pub.verify(c1, c2, zkp)); + zkp.d_[0] += 1; + CYBOZU_TEST_ASSERT(!pub.verify(c1, c2, zkp)); + } + CYBOZU_TEST_EXCEPTION(pub.encWithZkpBinEq(c1, c2, zkp, 2), cybozu::Exception); +} + +CYBOZU_TEST_AUTO(ZkpBinEq) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + ZkpBinEqTest(sec, pub); + + PrecomputedPublicKey ppub; + ppub.init(pub); + ZkpBinEqTest(sec, ppub); +} + +CYBOZU_TEST_AUTO(add_sub_mul) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + for (int m1 = -5; m1 < 5; m1++) { + for (int m2 = -5; m2 < 5; m2++) { + CipherText c1, c2, c3; + pub.enc(c1, m1); + pub.enc(c2, m2); + add(c3, c1, c2); + CYBOZU_TEST_EQUAL(m1 + m2, sec.dec(c3)); + + pub.reRand(c3); + CYBOZU_TEST_EQUAL(m1 + m2, sec.dec(c3)); + + sub(c3, c1, c2); + CYBOZU_TEST_EQUAL(m1 - m2, sec.dec(c3)); + + mul(c3, c1, 5); + CYBOZU_TEST_EQUAL(m1 * 5, sec.dec(c3)); + mul(c3, c1, -123); + CYBOZU_TEST_EQUAL(m1 * -123, sec.dec(c3)); + + mul(c3, c1, c2); + CYBOZU_TEST_EQUAL(m1 * m2, sec.dec(c3)); + + pub.reRand(c3); + CYBOZU_TEST_EQUAL(m1 * m2, sec.dec(c3)); + + CipherText::mul(c3, c3, -25); + CYBOZU_TEST_EQUAL(m1 * m2 * -25, sec.dec(c3)); + + pub.enc(c1, m1, true); + CYBOZU_TEST_EQUAL(m1, sec.dec(c1)); + pub.enc(c2, m2, true); + add(c3, c1, c2); + CYBOZU_TEST_EQUAL(m1 + m2, sec.dec(c3)); + } + } +} + +CYBOZU_TEST_AUTO(largeEnc) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + + Fr x; + x.setRand(); + CipherTextG1 c1, c2; + pub.enc(c1, x); + const int64_t m = 123; + pub.enc(c2, x + m); + sub(c1, c1, c2); + CYBOZU_TEST_EQUAL(sec.dec(c1), -m); + + pub.enc(c1, 0); + mul(c1, c1, x); + CYBOZU_TEST_ASSERT(sec.isZero(c1)); + pub.enc(c1, 1); + mul(c1, c1, x); + CYBOZU_TEST_ASSERT(!sec.isZero(c1)); +} + +CYBOZU_TEST_AUTO(add_mul_add_sub) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + int m[8] = { 1, -2, 3, 4, -5, 6, -7, 8 }; + CipherText c[8]; + for (int i = 0; i < 8; i++) { + pub.enc(c[i], m[i]); + CYBOZU_TEST_EQUAL(sec.dec(c[i]), m[i]); + CYBOZU_TEST_ASSERT(!c[i].isMultiplied()); + CipherText mc; + pub.convert(mc, c[i]); + CYBOZU_TEST_ASSERT(mc.isMultiplied()); + CYBOZU_TEST_EQUAL(sec.dec(mc), m[i]); + } + int ok1 = (m[0] + m[1]) * (m[2] + m[3]); + int ok2 = (m[4] + m[5]) * (m[6] + m[7]); + int ok = ok1 + ok2; + for (int i = 0; i < 4; i++) { + c[i * 2].add(c[i * 2 + 1]); + CYBOZU_TEST_EQUAL(sec.dec(c[i * 2]), m[i * 2] + m[i * 2 + 1]); + } + c[0].mul(c[2]); + CYBOZU_TEST_EQUAL(sec.dec(c[0]), ok1); + c[4].mul(c[6]); + CYBOZU_TEST_EQUAL(sec.dec(c[4]), ok2); + c[0].add(c[4]); + CYBOZU_TEST_EQUAL(sec.dec(c[0]), ok); + c[0].sub(c[4]); + CYBOZU_TEST_EQUAL(sec.dec(c[0]), ok1); +} + +CYBOZU_TEST_AUTO(finalExp) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + const int64_t m11 = 5; + const int64_t m12 = 3; + const int64_t m21 = -2; + const int64_t m22 = 9; + CipherTextG1 c11, c12; + CipherTextG2 c21, c22; + CipherTextGT ct1, ct2, ct; + pub.enc(c11, m11); + pub.enc(c12, m12); + pub.enc(c21, m21); + pub.enc(c22, m22); + CipherTextGT::mulML(ct1, c11, c21); + CipherTextGT::finalExp(ct, ct1); + CYBOZU_TEST_EQUAL(sec.dec(ct), m11 * m21); + CipherTextGT::mulML(ct2, c12, c22); + CipherTextGT::finalExp(ct, ct2); + CYBOZU_TEST_EQUAL(sec.dec(ct), m12 * m22); + CipherTextGT::add(ct1, ct1, ct2); + CipherTextGT::finalExp(ct1, ct1); + CYBOZU_TEST_EQUAL(sec.dec(ct1), (m11 * m21) + (m12 * m22)); +} + +CYBOZU_TEST_AUTO(innerProduct) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + + cybozu::XorShift rg; + const size_t n = 1000; + std::vector<int> v1, v2; + std::vector<CipherText> c1, c2; + v1.resize(n); + v2.resize(n); + c1.resize(n); + c2.resize(n); + int innerProduct = 0; + for (size_t i = 0; i < n; i++) { + v1[i] = rg() % 2; + v2[i] = rg() % 2; + innerProduct += v1[i] * v2[i]; + pub.enc(c1[i], v1[i]); + pub.enc(c2[i], v2[i]); + } + CipherText c, t; + CipherText::mul(c, c1[0], c2[0]); + for (size_t i = 1; i < n; i++) { + CipherText::mul(t, c1[i], c2[i]); + c.add(t); + } + CYBOZU_TEST_EQUAL(innerProduct, sec.dec(c)); +} + +template<class T> +T testIo(const T& x) +{ + std::stringstream ss; + ss << x; + T y; + ss >> y; + CYBOZU_TEST_EQUAL(x, y); + return y; +} + +CYBOZU_TEST_AUTO(io) +{ + setRangeForDLP(100); + int64_t m; + for (int i = 0; i < 2; i++) { + if (i == 1) { + Fp::setIoMode(mcl::IoSerialize); + G1::setIoMode(mcl::IoSerialize); + } + SecretKey sec; + sec.setByCSPRNG(); + testIo(sec); + PublicKey pub; + sec.getPublicKey(pub); + testIo(pub); + CipherTextG1 g1; + pub.enc(g1, 3); + m = sec.dec(testIo(g1)); + CYBOZU_TEST_EQUAL(m, 3); + CipherTextG2 g2; + pub.enc(g2, 5); + testIo(g2); + CipherTextA ca; + pub.enc(ca, -4); + m = sec.dec(testIo(ca)); + CYBOZU_TEST_EQUAL(m, -4); + CipherTextGT ct; + CipherTextGT::mul(ct, g1, g2); + m = sec.dec(testIo(ct)); + CYBOZU_TEST_EQUAL(m, 15); + } +} + +#ifndef PAPER +CYBOZU_TEST_AUTO(bench) +{ + const SecretKey& sec = g_sec; + PublicKey pub; + sec.getPublicKey(pub); + CipherText c1, c2, c3; + CYBOZU_BENCH("enc", pub.enc, c1, 5); + pub.enc(c2, 4); + CYBOZU_BENCH("add", c1.add, c2); + CYBOZU_BENCH("mul", CipherText::mul, c3, c1, c2); + pub.enc(c1, 5); + pub.enc(c2, 4); + c1.mul(c2); + CYBOZU_BENCH("dec", sec.dec, c1); + c2 = c1; + CYBOZU_BENCH("add after mul", c1.add, c2); +} +#endif + +CYBOZU_TEST_AUTO(saveHash) +{ + mcl::she::local::HashTable<G1> hashTbl1, hashTbl2; + hashTbl1.init(SHE::P_, 1234, 123); + std::stringstream ss; + hashTbl1.save(ss); + hashTbl2.load(ss); + CYBOZU_TEST_ASSERT(hashTbl1 == hashTbl2); +} + +static inline void putK(double t) { printf("%.2e\n", t * 1e-3); } + +template<class CT> +void decBench(const char *msg, int C, const SecretKey& sec, const PublicKey& pub, int64_t (SecretKey::*dec)(const CT& c) const = &SecretKey::dec) +{ + int64_t begin = 1 << 20; + int64_t end = 1LL << 32; + while (begin < end) { + CT c; + int64_t x = begin - 1; + pub.enc(c, x); + printf("m=%08x ", (uint32_t)x); + CYBOZU_BENCH_C(msg, C, (sec.*dec), c); + CYBOZU_TEST_EQUAL((sec.*dec)(c), x); + begin *= 2; + } + int64_t mTbl[] = { -0x80000003ll, 0x80000000ll, 0x80000005ll }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(mTbl); i++) { + int64_t m = mTbl[i]; + CT c; + pub.enc(c, m); + CYBOZU_TEST_EQUAL((sec.*dec)(c), m); + } +} + +#ifndef PAPER +CYBOZU_TEST_AUTO(hashBench) +{ + SecretKey& sec = g_sec; + sec.setByCSPRNG(); + const int C = 500; + const size_t hashSize = 1u << 21; + + clock_t begin = clock(), end; + setRangeForG1DLP(hashSize); + end = clock(); + printf("init G1 DLP %f\n", double(end - begin) / CLOCKS_PER_SEC); + begin = end; + setRangeForG2DLP(hashSize); + end = clock(); + printf("init G2 DLP %f\n", double(end - begin) / CLOCKS_PER_SEC); + begin = end; + setRangeForGTDLP(hashSize); + end = clock(); + printf("init GT DLP %f\n", double(end - begin) / CLOCKS_PER_SEC); + + PublicKey pub; + sec.getPublicKey(pub); + PrecomputedPublicKey ppub; + ppub.init(pub); + puts("Kclk"); + cybozu::bench::setPutCallback(putK); + decBench<CipherTextG1>("decG1", C, sec, pub); + puts(""); + decBench<CipherTextG2>("decG2", C, sec, pub); + puts(""); + decBench<CipherTextGT>("decGT", C, sec, pub); + puts(""); + decBench<CipherTextG1>("decG1ViaGT", C, sec, pub, &SecretKey::decViaGT); + puts(""); + decBench<CipherTextG2>("decG2ViaGT", C, sec, pub, &SecretKey::decViaGT); + + G1 P, P2; + G2 Q, Q2; + GT e, e2; + mpz_class mr; + { + Fr r; + r.setRand(); + mr = r.getMpz(); + } + hashAndMapToG1(P, "abc"); + hashAndMapToG2(Q, "abc"); + pairing(e, P, Q); + P2.clear(); + Q2.clear(); + e2 = 1; + + printf("large m\n"); + CYBOZU_BENCH_C("G1::add ", C, G1::add, P2, P2, P); + CYBOZU_BENCH_C("G1::mul ", C, G1::mul, P, P, mr); + CYBOZU_BENCH_C("G2::add ", C, G2::add, Q2, Q2, Q); + CYBOZU_BENCH_C("G2::mul ", C, G2::mul, Q, Q, mr); + CYBOZU_BENCH_C("GT::mul ", C, GT::mul, e2, e2, e); + CYBOZU_BENCH_C("GT::pow ", C, GT::pow, e, e, mr); + CYBOZU_BENCH_C("G1window", C, SHE::PhashTbl_.mulByWindowMethod, P2, mr); + CYBOZU_BENCH_C("G2window", C, SHE::QhashTbl_.mulByWindowMethod, Q2, mr); + CYBOZU_BENCH_C("GTwindow", C, SHE::ePQhashTbl_.mulByWindowMethod, e, mr); +#if 1 + typedef mcl::GroupMtoA<Fp12> AG; + mcl::fp::WindowMethod<AG> wm; + wm.init(static_cast<AG&>(e), Fr::getBitSize(), 10); + for (int i = 0; i < 100; i++) { + GT t1, t2; + GT::pow(t1, e, i); + wm.mul(static_cast<AG&>(t2), i); + CYBOZU_TEST_EQUAL(t1, t2); + } +// CYBOZU_BENCH_C("GTwindow", C, wm.mul, static_cast<AG&>(e), mr); +#endif + + CYBOZU_BENCH_C("miller ", C, millerLoop, e, P, Q); + CYBOZU_BENCH_C("finalExp", C, finalExp, e, e); + CYBOZU_BENCH_C("precomML", C, precomputedMillerLoop, e, P, SHE::Qcoeff_); + + CipherTextG1 c1; + CipherTextG2 c2; + CipherTextGT ct; + + int m = int(hashSize - 1); + printf("small m = %d\n", m); + CYBOZU_BENCH_C("G1::mul ", C, G1::mul, P, P, m); + CYBOZU_BENCH_C("G2::mul ", C, G2::mul, Q, Q, m); + CYBOZU_BENCH_C("GT::pow ", C, GT::pow, e, e, m); + CYBOZU_BENCH_C("G1window", C, SHE::PhashTbl_.mulByWindowMethod, P2, m); + CYBOZU_BENCH_C("G2window", C, SHE::QhashTbl_.mulByWindowMethod, Q2, m); + CYBOZU_BENCH_C("GTwindow", C, SHE::ePQhashTbl_.mulByWindowMethod, e, m); +// CYBOZU_BENCH_C("GTwindow", C, wm.mul, static_cast<AG&>(e), m); + + CYBOZU_BENCH_C("encG1 ", C, pub.enc, c1, m); + CYBOZU_BENCH_C("encG2 ", C, pub.enc, c2, m); + CYBOZU_BENCH_C("encGT ", C, pub.enc, ct, m); + CYBOZU_BENCH_C("encG1pre", C, ppub.enc, c1, m); + CYBOZU_BENCH_C("encG2pre", C, ppub.enc, c2, m); + CYBOZU_BENCH_C("encGTpre", C, ppub.enc, ct, m); + + CYBOZU_BENCH_C("decG1 ", C, sec.dec, c1); + CYBOZU_BENCH_C("decG2 ", C, sec.dec, c2); + CYBOZU_BENCH_C("degGT ", C, sec.dec, ct); + + CYBOZU_BENCH_C("CT:mul ", C, CipherTextGT::mul, ct, c1, c2); + CYBOZU_BENCH_C("CT:mulML", C, CipherTextGT::mulML, ct, c1, c2); + CYBOZU_BENCH_C("CT:finalExp", C, CipherTextGT::finalExp, ct, ct); + + CYBOZU_BENCH_C("addG1 ", C, CipherTextG1::add, c1, c1, c1); + CYBOZU_BENCH_C("addG2 ", C, CipherTextG2::add, c2, c2, c2); + CYBOZU_BENCH_C("addGT ", C, CipherTextGT::add, ct, ct, ct); + CYBOZU_BENCH_C("reRandG1", C, pub.reRand, c1); + CYBOZU_BENCH_C("reRandG2", C, pub.reRand, c2); + CYBOZU_BENCH_C("reRandGT", C, pub.reRand, ct); + CYBOZU_BENCH_C("reRandG1pre", C, ppub.reRand, c1); + CYBOZU_BENCH_C("reRandG2pre", C, ppub.reRand, c2); + CYBOZU_BENCH_C("reRandGTpre", C, ppub.reRand, ct); + CYBOZU_BENCH_C("mulG1 ", C, CipherTextG1::mul, c1, c1, m); + CYBOZU_BENCH_C("mulG2 ", C, CipherTextG2::mul, c2, c2, m); + CYBOZU_BENCH_C("mulGT ", C, CipherTextGT::mul, ct, ct, m); + + CYBOZU_BENCH_C("convG1toGT", C, pub.convert, ct, c1); + CYBOZU_BENCH_C("convG2toGT", C, pub.convert, ct, c2); +} +#endif + +CYBOZU_TEST_AUTO(liftedElGamal) +{ + const size_t hashSize = 1024; + initG1only(mcl::ecparam::secp192k1, hashSize); + const size_t byteSize = 192 / 8; + SecretKey sec; + sec.setByCSPRNG(); + PublicKey pub; + sec.getPublicKey(pub); + CipherTextG1 c1, c2, c3; + int m1 = 12, m2 = 34; + pub.enc(c1, m1); + pub.enc(c2, m2); + CYBOZU_TEST_EQUAL(sec.dec(c1), m1); + CYBOZU_TEST_EQUAL(sec.dec(c2), m2); + add(c3, c1, c2); + CYBOZU_TEST_EQUAL(sec.dec(c3), m1 + m2); + neg(c1, c2); + CYBOZU_TEST_EQUAL(sec.dec(c1), -m2); + mul(c1, c2, m1); + CYBOZU_TEST_EQUAL(sec.dec(c1), m2 * m1); + + char buf[1024]; + size_t n = sec.serialize(buf, sizeof(buf)); + CYBOZU_TEST_EQUAL(n, byteSize); + SecretKey sec2; + n = sec2.deserialize(buf, n); + CYBOZU_TEST_EQUAL(n, byteSize); + CYBOZU_TEST_EQUAL(sec, sec2); + + n = pub.serialize(buf, sizeof(buf)); + CYBOZU_TEST_EQUAL(n, byteSize + 1); // +1 is for sign of y + PublicKey pub2; + n = pub2.deserialize(buf, n); + CYBOZU_TEST_EQUAL(n, byteSize + 1); + CYBOZU_TEST_EQUAL(pub, pub2); + + PublicKey pub3; + sec2.getPublicKey(pub3); + CYBOZU_TEST_EQUAL(pub, pub3); +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/sq_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/sq_test.cpp new file mode 100644 index 000000000..4c386d23b --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/sq_test.cpp @@ -0,0 +1,21 @@ +#include <mcl/gmp_util.hpp> +#include <cybozu/test.hpp> +#include <iostream> + +CYBOZU_TEST_AUTO(sqrt) +{ + const int tbl[] = { 3, 5, 7, 11, 13, 17, 19, 257, 997, 1031 }; + mcl::SquareRoot sq; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const mpz_class p = tbl[i]; + sq.set(p); + for (mpz_class a = 0; a < p; a++) { + mpz_class x; + if (sq.get(x, a)) { + mpz_class y; + y = (x * x) % p; + CYBOZU_TEST_EQUAL(a, y); + } + } + } +} diff --git a/vendor/github.com/dexon-foundation/mcl/test/vint_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/vint_test.cpp new file mode 100644 index 000000000..15e14266a --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/vint_test.cpp @@ -0,0 +1,1353 @@ +#include <stdio.h> +#include <mcl/vint.hpp> +#include <iostream> +#include <sstream> +#include <set> +#include <cybozu/benchmark.hpp> +#include <cybozu/test.hpp> +#include <cybozu/xorshift.hpp> +#ifndef DONT_USE_GMP_IN_TEST +#include <gmpxx.h> +#endif + +#define PUT(x) std::cout << #x "=" << x << std::endl; + +#if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST) + #define MCL_AVOID_EXCEPTION_TEST +#endif + +using namespace mcl; + +struct V { + int n; + unsigned int p[16]; +}; + +CYBOZU_TEST_AUTO(addSub) +{ + static const struct { + V a; + V b; + V c; + } tbl[] = { + { + { 1, { 123, } }, + { 1, { 456, } }, + { 1, { 579, } }, + }, + { + { 1, { 0xffffffff, } }, + { 1, { 3, } }, + { 2, { 2, 1 } }, + }, + { + { 3, { 0xffffffff, 1, 0xffffffff } }, + { 2, { 1, 0xfffffffe, } }, + { 4, { 0, 0, 0, 1 } }, + }, + { + { 3, { 0xffffffff, 5, 0xffffffff } }, + { 2, { 1, 0xfffffffe, } }, + { 4, { 0, 4, 0, 1 } }, + }, + { + { 3, { 0xffffffff, 5, 0xffffffff } }, + { 1, { 1, } }, + { 3, { 0, 6, 0xffffffff } }, + }, + { + { 3, { 1, 0xffffffff, 1 } }, + { 3, { 0xffffffff, 0, 1 } }, + { 3, { 0, 0, 3 } }, + }, + { + { 1, { 1 } }, + { 3, { 0xffffffff, 0xffffffff, 0xffffffff } }, + { 4, { 0, 0, 0, 1 } }, + }, + { + { 1, { 0xffffffff } }, + { 1, { 0xffffffff } }, + { 2, { 0xfffffffe, 1 } }, + }, + { + { 2, { 0xffffffff, 0xffffffff } }, + { 2, { 0xffffffff, 0xffffffff } }, + { 3, { 0xfffffffe, 0xffffffff, 1 } }, + }, + { + { 3, { 0xffffffff, 0xffffffff, 0xffffffff } }, + { 3, { 0xffffffff, 0xffffffff, 0xffffffff } }, + { 4, { 0xfffffffe, 0xffffffff, 0xffffffff, 1 } }, + }, + { + { 4, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } }, + { 4, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } }, + { 5, { 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 1 } }, + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x, y, z, t; + x.setArray(tbl[i].a.p, tbl[i].a.n); + y.setArray(tbl[i].b.p, tbl[i].b.n); + z.setArray(tbl[i].c.p, tbl[i].c.n); + Vint::add(t, x, y); + CYBOZU_TEST_EQUAL(t, z); + + Vint::add(t, y, x); + CYBOZU_TEST_EQUAL(t, z); + + Vint::sub(t, z, x); + CYBOZU_TEST_EQUAL(t, y); + } + { + const uint32_t in[] = { 0xffffffff, 0xffffffff }; + const uint32_t out[] = { 0xfffffffe, 0xffffffff, 1 }; + Vint x, y; + x.setArray(in, 2); + y.setArray(out, 3); + Vint::add(x, x, x); + CYBOZU_TEST_EQUAL(x, y); + Vint::sub(x, x, x); + y.clear(); + CYBOZU_TEST_EQUAL(x, y); + } + { + const uint32_t t0[] = {1, 2}; + const uint32_t t1[] = {3, 4, 5}; + const uint32_t t2[] = {4, 6, 5}; + Vint x, y, z; + z.setArray(t2, 3); + + x.setArray(t0, 2); + y.setArray(t1, 3); + Vint::add(x, x, y); + CYBOZU_TEST_EQUAL(x, z); + + x.setArray(t0, 2); + y.setArray(t1, 3); + Vint::add(x, y, x); + CYBOZU_TEST_EQUAL(x, z); + + x.setArray(t0, 2); + y.setArray(t1, 3); + Vint::add(y, x, y); + CYBOZU_TEST_EQUAL(y, z); + + x.setArray(t0, 2); + y.setArray(t1, 3); + Vint::add(y, y, x); + CYBOZU_TEST_EQUAL(y, z); + } +} + +CYBOZU_TEST_AUTO(mul1) +{ + static const struct { + V a; + int b; + V c; + } tbl[] = { + { + { 1, { 12, } }, + 5, + { 1, { 60, } }, + }, + { + { 1, { 1234567, } }, + 1, + { 1, { 1234567, } }, + }, + { + { 1, { 1234567, } }, + 89012345, + { 2, { 0x27F6EDCF, 0x63F2, } }, + }, + { + { 3, { 0xffffffff, 0xffffffff, 0xffffffff, } }, + 0x7fffffff, + { 4, { 0x80000001, 0xffffffff, 0xffffffff, 0x7ffffffe } }, + }, + { + { 3, { 0xffffffff, 0xffffffff, 0xffffffff, } }, + 1, + { 3, { 0xffffffff, 0xffffffff, 0xffffffff, } }, + }, + { + { 2, { 0xffffffff, 1 } }, + 0x7fffffff, + { 2, { 0x80000001, 0xfffffffd } }, + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x, z, t; + int y; + x.setArray(tbl[i].a.p, tbl[i].a.n); + y = tbl[i].b; + z.setArray(tbl[i].c.p, tbl[i].c.n); + Vint::mul(t, x, y); + CYBOZU_TEST_EQUAL(t, z); + + Vint::mul(x, x, y); + CYBOZU_TEST_EQUAL(x, z); + } +} + +CYBOZU_TEST_AUTO(mul2) +{ + static const struct { + V a; + V b; + V c; + } tbl[] = { + { + { 1, { 12, } }, + { 1, { 5, } }, + { 1, { 60, } }, + }, + { + { 1, { 1234567, } }, + { 1, { 89012345, } }, + { 2, { 0x27F6EDCF, 0x63F2, } }, + }, + { + { 3, { 0xffffffff, 0xffffffff, 0xffffffff, } }, + { 1, { 0xffffffff, } }, + { 4, { 0x00000001, 0xffffffff, 0xffffffff, 0xfffffffe } }, + }, + { + { 2, { 0xffffffff, 1 } }, + { 1, { 0xffffffff, } }, + { 3, { 0x00000001, 0xfffffffd, 1 } }, + }, + { + { 2, { 0xffffffff, 1 } }, + { 1, { 0xffffffff, } }, + { 3, { 0x00000001, 0xfffffffd, 1 } }, + }, + { + { 2, { 1, 1 } }, + { 2, { 1, 1 } }, + { 3, { 1, 2, 1 } }, + }, + { + { 3, { 0xffffffff, 0xffffffff, 1 } }, + { 2, { 0xffffffff, 0xffffffff } }, + { 5, { 1, 0, 0xfffffffd, 0xffffffff, 1 } }, + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x, y, z, t; + x.setArray(tbl[i].a.p, tbl[i].a.n); + y.setArray(tbl[i].b.p, tbl[i].b.n); + z.setArray(tbl[i].c.p, tbl[i].c.n); + Vint::mul(t, x, y); + CYBOZU_TEST_EQUAL(t, z); + + Vint::mul(t, y, x); + CYBOZU_TEST_EQUAL(t, z); + } + { + const uint32_t in[] = { 0xffffffff, 1 }; + const uint32_t out[] = { 1, 0xfffffffc, 3 }; + Vint x, y, z; + y.setArray(out, 3); + x.setArray(in, 2); + z = x; + Vint::mul(x, x, x); + CYBOZU_TEST_EQUAL(x, y); + + x.setArray(in, 2); + Vint::mul(x, x, z); + CYBOZU_TEST_EQUAL(x, y); + + x.setArray(in, 2); + Vint::mul(x, z, x); + CYBOZU_TEST_EQUAL(x, y); + + x.setArray(in, 2); + Vint::mul(x, z, z); + CYBOZU_TEST_EQUAL(x, y); + } + { + Vint a("285434247217355341057"); + a *= a; + CYBOZU_TEST_EQUAL(a, Vint("81472709484538325259309302444004789877249")); + } +} + +CYBOZU_TEST_AUTO(div1) +{ + static const struct { + V a; + unsigned int b; + unsigned int r; + V c; + } tbl[] = { + { + { 1, { 100, } }, + 1, 0, + { 1, { 100, } }, + }, + { + { 1, { 100, } }, + 100, 0, + { 1, { 1, } }, + }, + { + { 1, { 100, } }, + 101, 100, + { 1, { 0, } }, + }, + { + { 1, { 100, } }, + 2, 0, + { 1, { 50, } }, + }, + { + { 1, { 100, } }, + 3, 1, + { 1, { 33, } }, + }, + { + { 2, { 0xffffffff, 0xffffffff } }, + 1, 0, + { 2, { 0xffffffff, 0xffffffff, } }, + }, + { + { 2, { 0xffffffff, 0xffffffff } }, + 123, 15, + { 2, { 0x4d0214d0, 0x214d021 } }, + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x, z, t; + unsigned int b, r, u; + x.setArray(tbl[i].a.p, tbl[i].a.n); + b = tbl[i].b; + r = tbl[i].r; + z.setArray(tbl[i].c.p, tbl[i].c.n); + + u = (unsigned int)Vint::divMods1(&t, x, b); + CYBOZU_TEST_EQUAL(t, z); + CYBOZU_TEST_EQUAL(u, r); + + u = (unsigned int)Vint::divMods1(&x, x, b); + CYBOZU_TEST_EQUAL(x, z); + CYBOZU_TEST_EQUAL(u, r); + } +} + +CYBOZU_TEST_AUTO(div2) +{ + static const struct { + V x; + V y; + V q; + V r; + } tbl[] = { + { + { 1, { 100 } }, + { 1, { 3 } }, + { 1, { 33 } }, + { 1, { 1 } }, + }, + { + { 2, { 1, 1 } }, + { 2, { 0, 1 } }, + { 1, { 1 } }, + { 1, { 1 } }, + }, + { + { 2, { 0xffffffff, 0xffffffff } }, + { 2, { 0, 1 } }, + { 1, { 0xffffffff } }, + { 1, { 0xffffffff } }, + }, + { + { 2, { 0xffffffff, 0xffffffff } }, + { 2, { 0xffffffff, 1 } }, + { 1, { 0x80000000 } }, + { 1, { 0x7fffffff } }, + }, + { + { 3, { 0xffffffff, 0xffffffff, 0xffffffff } }, + { 2, { 0xffffffff, 1 } }, + { 2, { 0x40000000, 0x80000000 } }, + { 1, { 0x3fffffff } }, + }, + { + { 4, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } }, + { 3, { 1, 0, 1 } }, + { 2, { 0xffffffff, 0xffffffff } }, + { 1, { 0 } }, + }, + { + { 4, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } }, + { 3, { 1, 0xffffffff, 0xffffffff } }, + { 2, { 0, 1 } }, + { 2, { 0xffffffff, 0xfffffffe } }, + }, + { + { 4, { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } }, + { 3, { 1, 0, 0xffffffff } }, + { 2, { 1, 1 } }, + { 2, { 0xfffffffe, 0xfffffffe } }, + }, + { + { 4, { 0xffffffff, 0xffffffff, 0xffffffff, 1 } }, + { 3, { 1, 0, 0xffffffff } }, + { 1, { 2 } }, + { 3, { 0xfffffffd, 0xffffffff, 1 } }, + }, + { + { 4, { 0, 0, 1, 1 } }, + { 2, { 1, 1 } }, + { 3, { 0, 0, 1 } }, + { 1, { 0 } }, + }, + { + { 3, { 5, 5, 1} }, + { 2, { 1, 2 } }, + { 1, { 0x80000002 } }, + { 1, { 0x80000003, } }, + }, + { + { 2, { 5, 5} }, + { 2, { 1, 1 } }, + { 1, { 5 } }, + { 1, { 0, } }, + }, + { + { 2, { 5, 5} }, + { 2, { 2, 1 } }, + { 1, { 4 } }, + { 1, { 0xfffffffd, } }, + }, + { + { 3, { 5, 0, 5} }, + { 3, { 2, 0, 1 } }, + { 1, { 4 } }, + { 2, { 0xfffffffd, 0xffffffff } }, + }, + { + { 2, { 4, 5 } }, + { 2, { 5, 5 } }, + { 1, { 0 } }, + { 2, { 4, 5 } }, + }, + { + { 1, { 123 } }, + { 2, { 1, 1 } }, + { 1, { 0 } }, + { 1, { 123 } }, + }, + { + { 1, { 123 } }, + { 3, { 1, 1, 1 } }, + { 1, { 0 } }, + { 1, { 123 } }, + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x, y, q, r; + x.setArray(tbl[i].x.p, tbl[i].x.n); + y.setArray(tbl[i].y.p, tbl[i].y.n); + q.setArray(tbl[i].q.p, tbl[i].q.n); + r.setArray(tbl[i].r.p, tbl[i].r.n); + + Vint qt, rt; + Vint::quotRem(&qt, rt, x, y); + CYBOZU_TEST_EQUAL(qt, q); + CYBOZU_TEST_EQUAL(rt, r); + + Vint::mul(y, y, qt); + Vint::add(y, y, rt); + CYBOZU_TEST_EQUAL(x, y); + + x.setArray(tbl[i].x.p, tbl[i].x.n); + y.setArray(tbl[i].y.p, tbl[i].y.n); + Vint::quotRem(&x, rt, x, y); + CYBOZU_TEST_EQUAL(x, q); + CYBOZU_TEST_EQUAL(rt, r); + + x.setArray(tbl[i].x.p, tbl[i].x.n); + y.setArray(tbl[i].y.p, tbl[i].y.n); + Vint::quotRem(&y, rt, x, y); + CYBOZU_TEST_EQUAL(y, q); + CYBOZU_TEST_EQUAL(rt, r); + + x.setArray(tbl[i].x.p, tbl[i].x.n); + y.setArray(tbl[i].y.p, tbl[i].y.n); + Vint::quotRem(&x, y, x, y); + CYBOZU_TEST_EQUAL(x, q); + CYBOZU_TEST_EQUAL(y, r); + + x.setArray(tbl[i].x.p, tbl[i].x.n); + y.setArray(tbl[i].y.p, tbl[i].y.n); + Vint::quotRem(&y, x, x, y); + CYBOZU_TEST_EQUAL(y, q); + CYBOZU_TEST_EQUAL(x, r); + } + { + const uint32_t in[] = { 1, 1 }; + Vint x, y, z; + x.setArray(in, 2); + Vint::quotRem(&x, y, x, x); + z = 1; + CYBOZU_TEST_EQUAL(x, z); + z.clear(); + CYBOZU_TEST_EQUAL(y, z); + + Vint::quotRem(&y, x, x, x); + z = 1; + CYBOZU_TEST_EQUAL(y, z); + z.clear(); + CYBOZU_TEST_EQUAL(x, z); + } +} + +CYBOZU_TEST_AUTO(quotRem) +{ + const struct { + const char *x; + const char *y; + const char *r; + } tbl[] = { + { + "1448106640508192452750709206294683535529268965445799785581837640324321797831381715960812126274894517677713278300997728292641936248881345120394299128611830", + "82434016654300679721217353503190038836571781811386228921167322412819029493183", + "72416512377294697540770834088766459385112079195086911762075702918882982361282" + }, + { + "97086308670107713719105336221824613370040805954034005192338040686500414395543303807941158656814978071549225072789349941064484974666540443679601226744652", + "82434016654300679721217353503190038836571781811386228921167322412819029493183", + "41854959563040430269871677548536437787164514279279911478858426970427834388586", + }, + { + "726838724295606887174238120788791626017347752989142414466410919788841485181240131619880050064495352797213258935807786970844241989010252", + "82434016654300679721217353503190038836571781811386228921167322412819029493183", + "81378967132566843036693176764684783485107373533583677681931133755003929106966", + }, + { + "85319207237201203511459960875801690195851794174784746933408178697267695525099750", + "82434016654300679721217353503190038836571781811386228921167322412819029493183", + "82434016654300679721217353503190038836571781811386228921167322412819029148528", + }, + { + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x100000000000000000000000000000000000000000000000001", + "1606938044258990275541962092341162602522202993782724115824640", + }, + { + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x1000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "34175792574734561318320347298712833833643272357332299899995954578095372295314880347335474659983360", + }, + { + "0xfffffffffffff000000000000000000000000000000000000000000000000000000000000000000", + "0x100000000000000000000000000000000000000000000000000000000000000000001", + "7558907585412001237250713901367146624661464598973016020495791084036551510708977665", + }, + { + "0xfffffffffffff000000000000000000000000000000000000000000000000000000000000000000", + "0xfffffffffffff0000000000000000000000000000000000000000000000000000000000000001", + "521481209941628322292632858916605385658190900090571826892867289394157573281830188869820088065", + }, + { + "0x1230000000000000456", + "0x1230000000000000457", + "0x1230000000000000456", + }, + { + "0x1230000000000000456", + "0x1230000000000000456", + "0", + }, + { + "0x1230000000000000456", + "0x1230000000000000455", + "1", + }, + { + "0x1230000000000000456", + "0x2000000000000000000", + "0x1230000000000000456", + }, + { + "0xffffffffffffffffffffffffffffffff", + "0x80000000000000000000000000000000", + "0x7fffffffffffffffffffffffffffffff", + }, + { + "0xffffffffffffffffffffffffffffffff", + "0x7fffffffffffffffffffffffffffffff", + "1", + }, + { + "0xffffffffffffffffffffffffffffffff", + "0x70000000000000000000000000000000", + "0x1fffffffffffffffffffffffffffffff", + }, + { + "0xffffffffffffffffffffffffffffffff", + "0x30000000000000000000000000000000", + "0x0fffffffffffffffffffffffffffffff", + }, + { + "0xffffffffffffffffffffffffffffffff", + "0x10000000000000000000000000000000", + "0x0fffffffffffffffffffffffffffffff", + }, + { + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x2523648240000001ba344d80000000086121000000000013a700000000000013", + "0x212ba4f27ffffff5a2c62effffffffcdb939ffffffffff8a15ffffffffffff8d", + }, + { + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d", + "0x212ba4f27ffffff5a2c62effffffffd00242ffffffffff9c39ffffffffffffb1", + }, + }; + mcl::Vint x, y, q, r1, r2; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + x.setStr(tbl[i].x); + y.setStr(tbl[i].y); + r1.setStr(tbl[i].r); + mcl::Vint::divMod(&q, r2, x, y); + CYBOZU_TEST_EQUAL(r1, r2); + CYBOZU_TEST_EQUAL(x, q * y + r2); + } +} + +CYBOZU_TEST_AUTO(string) +{ + const struct { + uint32_t v[5]; + size_t vn; + const char *str; + const char *hex; + const char *bin; + } tbl[] = { + { { 0 }, 0, "0", "0x0", "0b0" }, + { { 12345 }, 1, "12345", "0x3039", "0b11000000111001" }, + { { 0xffffffff }, 1, "4294967295", "0xffffffff", "0b11111111111111111111111111111111" }, + { { 0, 1 }, 2, "4294967296", "0x100000000", "0b100000000000000000000000000000000" }, + { { 0, 0, 0, 0, 1 }, 5, "340282366920938463463374607431768211456", "0x100000000000000000000000000000000", "0b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, + { { 0, 0x0b22a000, 0xe2f768a0, 0xe086b93c, 0x2cd76f }, 5, "1000000000000000000000000000000000000000000000", "0x2cd76fe086b93ce2f768a00b22a00000000000", "0b101100110101110110111111100000100001101011100100111100111000101111011101101000101000000000101100100010101000000000000000000000000000000000000000000000" }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x, y; + x.setArray(tbl[i].v,tbl[i].vn); + CYBOZU_TEST_EQUAL(x.getStr(10), tbl[i].str); + char buf[1024]; + size_t n = x.getStr(buf, sizeof(buf), 10); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL(tbl[i].str, buf); + y.setStr(tbl[i].str); + CYBOZU_TEST_EQUAL(x.getStr(16), tbl[i].hex + 2); + n = x.getStr(buf, sizeof(buf), 16); + CYBOZU_TEST_ASSERT(n > 0); + CYBOZU_TEST_EQUAL(tbl[i].hex + 2, buf); + CYBOZU_TEST_EQUAL(x, y); + x = 1; + x.setStr(tbl[i].hex); + CYBOZU_TEST_EQUAL(x, y); + } +} + +CYBOZU_TEST_AUTO(shift) +{ + Vint x("123423424918471928374192874198274981274918274918274918243"); + Vint y, z; + + const size_t unitBitSize = Vint::unitBitSize; + Vint s; + // shl + for (size_t i = 1; i < 31; i++) { + Vint::shl(y, x, i); + z = x * (Vint::Unit(1) << i); + CYBOZU_TEST_EQUAL(y, z); + y = x << i; + CYBOZU_TEST_EQUAL(y, z); + y = x; + y <<= i; + CYBOZU_TEST_EQUAL(y, z); + } + for (int i = 0; i < 4; i++) { + Vint::shl(y, x, i * unitBitSize); + Vint::pow(s, Vint(2), i * unitBitSize); + z = x * s; + CYBOZU_TEST_EQUAL(y, z); + y = x << (i * unitBitSize); + CYBOZU_TEST_EQUAL(y, z); + y = x; + y <<= (i * unitBitSize); + CYBOZU_TEST_EQUAL(y, z); + } + for (int i = 0; i < 100; i++) { + y = x << i; + Vint::pow(s, Vint(2), i); + z = x * s; + CYBOZU_TEST_EQUAL(y, z); + y = x; + y <<= i; + CYBOZU_TEST_EQUAL(y, z); + } + + // shr + for (size_t i = 1; i < 31; i++) { + Vint::shr(y, x, i); + z = x / (Vint::Unit(1) << i); + CYBOZU_TEST_EQUAL(y, z); + y = x >> i; + CYBOZU_TEST_EQUAL(y, z); + y = x; + y >>= i; + CYBOZU_TEST_EQUAL(y, z); + } + for (int i = 0; i < 3; i++) { + Vint::shr(y, x, i * unitBitSize); + Vint::pow(s, Vint(2), i * unitBitSize); + z = x / s; + CYBOZU_TEST_EQUAL(y, z); + y = x >> (i * unitBitSize); + CYBOZU_TEST_EQUAL(y, z); + y = x; + y >>= (i * unitBitSize); + CYBOZU_TEST_EQUAL(y, z); + } + for (int i = 0; i < 100; i++) { + y = x >> i; + Vint::pow(s, Vint(2), i); + z = x / s; + CYBOZU_TEST_EQUAL(y, z); + y = x; + y >>= i; + CYBOZU_TEST_EQUAL(y, z); + } + { + Vint a = 0, zero = 0; + a <<= Vint::unitBitSize; + CYBOZU_TEST_EQUAL(a, zero); + } +} + +CYBOZU_TEST_AUTO(getBitSize) +{ + { + Vint zero = 0; + CYBOZU_TEST_EQUAL(zero.getBitSize(), 1); + zero <<= (Vint::unitBitSize - 1); + CYBOZU_TEST_EQUAL(zero.getBitSize(), 1); + zero <<= Vint::unitBitSize; + CYBOZU_TEST_EQUAL(zero.getBitSize(), 1); + } + + { + Vint a = 1; + CYBOZU_TEST_EQUAL(a.getBitSize(), 1); + a = 2; + CYBOZU_TEST_EQUAL(a.getBitSize(), 2); + a = 3; + CYBOZU_TEST_EQUAL(a.getBitSize(), 2); + a = 4; + CYBOZU_TEST_EQUAL(a.getBitSize(), 3); + } + + { + Vint a = 5; + const size_t msbindex = a.getBitSize(); + const size_t width = 100; + const size_t time = 3; + for (size_t i = 0; i < time; ++i) { + a <<= width; + CYBOZU_TEST_EQUAL(a.getBitSize(), msbindex + width*(i + 1)); + } + + for (size_t i = 0; i < time*2; ++i) { + a >>= width/2; + CYBOZU_TEST_EQUAL(a.getBitSize(), msbindex + width*time - (width/2)*(i + 1)); + } + a >>= width; + CYBOZU_TEST_ASSERT(a.isZero()); + CYBOZU_TEST_EQUAL(a.getBitSize(), 1); + } + + { + Vint b("12"), c("345"), d("67890"); + size_t bl = b.getBitSize(), cl = c.getBitSize(), dl = d.getBitSize(); + CYBOZU_TEST_ASSERT((b*c).getBitSize() <= bl + cl); + CYBOZU_TEST_ASSERT((c*d).getBitSize() <= cl + dl); + CYBOZU_TEST_ASSERT((b*c*d).getBitSize() <= bl + cl + dl); + } +} + +CYBOZU_TEST_AUTO(bit) +{ + Vint a; + a.setStr("0x1234567890abcdef"); + bool tvec[] = { + 1,1,1,1,0 ,1,1,1,1,0 + ,1,1,0,0,1 ,1,1,1,0,1 + ,0,1,0,1,0 ,0,0,0,1,0 + ,0,1,0,0,0 ,1,1,1,1,0 + ,0,1,1,0,1 ,0,1,0,0,0 + ,1,0,1,1,0 ,0,0,1,0,0 + ,1 + }; + CYBOZU_TEST_EQUAL(a.getBitSize(), sizeof(tvec)/sizeof(*tvec)); + for (int i = (int)a.getBitSize() - 1; i >= 0; --i) { + CYBOZU_TEST_EQUAL(a.testBit(i), tvec[i]); + } +} + +CYBOZU_TEST_AUTO(sample) +{ + using namespace mcl; + Vint x(1); + Vint y("123456789"); + Vint z; + + x = 1; // set by int + y.setStr("123456789"); // set by decimal + z.setStr("0xffffffff"); // set by hex + x += z; + + x = 2; + y = 250; + Vint::pow(x, x, y); + Vint r, q; + r = x % y; + q = x / y; + CYBOZU_TEST_EQUAL(q * y + r, x); + + Vint::quotRem(&q, r, x, y); // get both r and q + CYBOZU_TEST_EQUAL(q * y + r, x); +} + +CYBOZU_TEST_AUTO(Vint) +{ + const struct { + int a; + int b; + /* + q, r ; like C + q2, r2 ; like Python + */ + int add, sub, mul, q, r, q2, r2; + } tbl[] = { + { 13, 5, 18, 8, 65, 2, 3, 2, 3 }, + { 13, -5, 8, 18, -65, -2, 3, -3, -2 }, + { -13, 5, -8, -18, -65, -2, -3, -3, 2 }, + { -13, -5, -18, -8, 65, 2, -3, 2, -3 }, + { 5, 13, 18, -8, 65, 0, 5 , 0, 5}, + { 5, -13, -8, 18, -65, 0, 5 , -1, -8}, + { -5, 13, 8, -18, -65, 0, -5 , -1, 8}, + { -5, -13, -18, 8, 65, 0, -5 , 0, -5}, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint a = tbl[i].a; + Vint b = tbl[i].b; + Vint add = a + b; + Vint sub = a - b; + Vint mul = a * b; + Vint q = a / b; + Vint r = a % b; + Vint q2, r2; + Vint::quotRem(&q2, r2, a, b); + CYBOZU_TEST_EQUAL(add, tbl[i].add); + CYBOZU_TEST_EQUAL(sub, tbl[i].sub); + CYBOZU_TEST_EQUAL(mul, tbl[i].mul); + CYBOZU_TEST_EQUAL(q, tbl[i].q); + CYBOZU_TEST_EQUAL(r, tbl[i].r); + CYBOZU_TEST_EQUAL(q * b + r, a); + CYBOZU_TEST_EQUAL(q2, tbl[i].q2); + CYBOZU_TEST_EQUAL(r2, tbl[i].r2); + CYBOZU_TEST_EQUAL(q2 * b + r2, a); + } + CYBOZU_TEST_EQUAL(Vint("15") / Vint("3"), Vint("5")); + CYBOZU_TEST_EQUAL(Vint("15") / Vint("-3"), Vint("-5")); + CYBOZU_TEST_EQUAL(Vint("-15") / Vint("3"), Vint("-5")); + CYBOZU_TEST_EQUAL(Vint("-15") / Vint("-3"), Vint("5")); + + CYBOZU_TEST_EQUAL(Vint("15") % Vint("3"), Vint("0")); + CYBOZU_TEST_EQUAL(Vint("15") % Vint("-3"), Vint("0")); + CYBOZU_TEST_EQUAL(Vint("-15") % Vint("3"), Vint("0")); + CYBOZU_TEST_EQUAL(Vint("-15") % Vint("-3"), Vint("0")); + + CYBOZU_TEST_EQUAL(Vint("-0") + Vint("-3"), Vint("-3")); + CYBOZU_TEST_EQUAL(Vint("-0") - Vint("-3"), Vint("3")); + CYBOZU_TEST_EQUAL(Vint("-3") + Vint("-0"), Vint("-3")); + CYBOZU_TEST_EQUAL(Vint("-3") - Vint("-0"), Vint("-3")); + + CYBOZU_TEST_EQUAL(Vint("-0") + Vint("3"), Vint("3")); + CYBOZU_TEST_EQUAL(Vint("-0") - Vint("3"), Vint("-3")); + CYBOZU_TEST_EQUAL(Vint("3") + Vint("-0"), Vint("3")); + CYBOZU_TEST_EQUAL(Vint("3") - Vint("-0"), Vint("3")); + + CYBOZU_TEST_EQUAL(Vint("0"), Vint("0")); + CYBOZU_TEST_EQUAL(Vint("0"), Vint("-0")); + CYBOZU_TEST_EQUAL(Vint("-0"), Vint("0")); + CYBOZU_TEST_EQUAL(Vint("-0"), Vint("-0")); + + CYBOZU_TEST_ASSERT(Vint("2") < Vint("3")); + CYBOZU_TEST_ASSERT(Vint("-2") < Vint("3")); + CYBOZU_TEST_ASSERT(Vint("-5") < Vint("-3")); + CYBOZU_TEST_ASSERT(Vint("-0") < Vint("1")); + CYBOZU_TEST_ASSERT(Vint("-1") < Vint("-0")); + + CYBOZU_TEST_ASSERT(Vint("5") > Vint("3")); + CYBOZU_TEST_ASSERT(Vint("5") > Vint("-3")); + CYBOZU_TEST_ASSERT(Vint("-2") > Vint("-3")); + CYBOZU_TEST_ASSERT(Vint("3") > Vint("-0")); + CYBOZU_TEST_ASSERT(Vint("-0") > Vint("-1")); + + { + const struct { + const char *str; + int s; + int shl; + int shr; + } tbl2[] = { + { "0", 1, 0, 0 }, + { "-0", 1, 0, 0 }, + { "1", 1, 2, 0 }, + { "-1", 1, -2, 0 }, + { "12345", 3, 98760, 1543 }, + { "-12345", 3, -98760, 0 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl2); i++) { + Vint a = Vint(tbl2[i].str); + Vint shl = a << tbl2[i].s; + CYBOZU_TEST_EQUAL(shl, tbl2[i].shl); + if (!a.isNegative()) { + Vint shr = a >> tbl2[i].s; + CYBOZU_TEST_EQUAL(shr, tbl2[i].shr); + } + } + } +} + +CYBOZU_TEST_AUTO(add2) +{ + Vint x, y, z, w; + x.setStr("2416089439321382744001761632872637936198961520379024187947524965775137204955564426500438089001375107581766516460437532995850581062940399321788596606850"); + y.setStr("2416089439321382743300544243711595219403446085161565705825288050160594425031420687263897209379984490503106207071010949258995096347962762372787916800000"); + z.setStr("701217389161042716795515435217458482122236915614542779924143739236540879621390617078660309389426583736855484714977636949000679806850"); + Vint::sub(w, x, y); + CYBOZU_TEST_EQUAL(w, z); + + Vint a, c, d; + + a.setStr("-2416089439321382744001761632872637936198961520379024187947524965775137204955564426500438089001375107581766516460437532995850581062940399321788596606850"); + c.setStr("2416089439321382743300544243711595219403446085161565705825288050160594425031420687263897209379984490503106207071010949258995096347962762372787916800000"); + a = a + c; + + d.setStr("-701217389161042716795515435217458482122236915614542779924143739236540879621390617078660309389426583736855484714977636949000679806850"); + CYBOZU_TEST_EQUAL(a, d); +} + +CYBOZU_TEST_AUTO(stream) +{ + { + Vint x, y, z, w; + x.setStr("12345678901232342424242423423429922"); + y.setStr("23423423452424242343"); + std::ostringstream oss; + oss << x << ' ' << y; + std::istringstream iss(oss.str()); + iss >> z >> w; + CYBOZU_TEST_EQUAL(x, z); + CYBOZU_TEST_EQUAL(y, w); + } + { + Vint x, y, z, w; + x.setStr("0x100"); + y.setStr("123"); + std::ostringstream oss; + oss << x << ' ' << y; + std::istringstream iss(oss.str()); + iss >> z >> w; + CYBOZU_TEST_EQUAL(x, z); + CYBOZU_TEST_EQUAL(y, w); + } + { + Vint x, y, z, w; + x.setStr("12345678901232342424242423423429922"); + y.setStr("-23423423452424242343"); + std::ostringstream oss; + oss << x << ' ' << y; + std::istringstream iss(oss.str()); + iss >> z >> w; + CYBOZU_TEST_EQUAL(x, z); + CYBOZU_TEST_EQUAL(y, w); + } +} + +CYBOZU_TEST_AUTO(inc_dec) +{ + Vint x = 3; + CYBOZU_TEST_EQUAL(x++, 3); + CYBOZU_TEST_EQUAL(x, 4); + CYBOZU_TEST_EQUAL(++x, 5); + CYBOZU_TEST_EQUAL(x, 5); + + CYBOZU_TEST_EQUAL(x--, 5); + CYBOZU_TEST_EQUAL(x, 4); + CYBOZU_TEST_EQUAL(--x, 3); + CYBOZU_TEST_EQUAL(x, 3); +} + +CYBOZU_TEST_AUTO(withInt) +{ + Vint x = 15; + x += 3; + CYBOZU_TEST_EQUAL(x, 18); + x -= 2; + CYBOZU_TEST_EQUAL(x, 16); + x *= 2; + CYBOZU_TEST_EQUAL(x, 32); + x /= 3; + CYBOZU_TEST_EQUAL(x, 10); + x = -x; + CYBOZU_TEST_EQUAL(x, -10); + x += 1; + CYBOZU_TEST_EQUAL(x, -9); + x -= 2; + CYBOZU_TEST_EQUAL(x, -11); + x *= 2; + CYBOZU_TEST_EQUAL(x, -22); + x /= 5; + CYBOZU_TEST_EQUAL(x, -4); + x = -22; + x %= 5; + CYBOZU_TEST_EQUAL(x, -2); + + x = 3; + x += -2; + CYBOZU_TEST_EQUAL(x, 1); + x += -5; + CYBOZU_TEST_EQUAL(x, -4); + x -= -7; + CYBOZU_TEST_EQUAL(x, 3); + x *= -1; + CYBOZU_TEST_EQUAL(x, -3); + x /= -1; + CYBOZU_TEST_EQUAL(x, 3); + + x++; + CYBOZU_TEST_EQUAL(x, 4); + x--; + CYBOZU_TEST_EQUAL(x, 3); + x = -3; + x++; + CYBOZU_TEST_EQUAL(x, -2); + x--; + CYBOZU_TEST_EQUAL(x, -3); + + ++x; + CYBOZU_TEST_EQUAL(x, -2); + --x; + CYBOZU_TEST_EQUAL(x, -3); + x = 3; + ++x; + CYBOZU_TEST_EQUAL(x, 4); + --x; + CYBOZU_TEST_EQUAL(x, 3); +} + +CYBOZU_TEST_AUTO(addu1) +{ + Vint x = 4; + Vint::addu1(x, x, 2); + CYBOZU_TEST_EQUAL(x, 6); + Vint::subu1(x, x, 2); + CYBOZU_TEST_EQUAL(x, 4); + Vint::subu1(x, x, 10); + CYBOZU_TEST_EQUAL(x, -6); + x = -4; + Vint::addu1(x, x, 2); + CYBOZU_TEST_EQUAL(x, -2); + Vint::subu1(x, x, 2); + CYBOZU_TEST_EQUAL(x, -4); + Vint::addu1(x, x, 10); + CYBOZU_TEST_EQUAL(x, 6); + + x.setStr("0x10000000000000000000000002"); + Vint::subu1(x, x, 3); + CYBOZU_TEST_EQUAL(x, Vint("0xfffffffffffffffffffffffff")); + x.setStr("-0x10000000000000000000000000"); + Vint::addu1(x, x, 5); + CYBOZU_TEST_EQUAL(x, Vint("-0xffffffffffffffffffffffffb")); +} + +CYBOZU_TEST_AUTO(pow) +{ + Vint x = 2; + Vint y; + Vint::pow(y, x, 3); + CYBOZU_TEST_EQUAL(y, 8); + x = -2; + Vint::pow(y, x, 3); + CYBOZU_TEST_EQUAL(y, -8); +#ifndef MCL_AVOID_EXCEPTION_TEST +// CYBOZU_TEST_EXCEPTION(Vint::pow(y, x, -2), cybozu::Exception); +#endif +} + +CYBOZU_TEST_AUTO(powMod) +{ + Vint x = 7; + Vint m = 65537; + Vint y; + Vint::powMod(y, x, 20, m); + CYBOZU_TEST_EQUAL(y, 55277); + Vint::powMod(y, x, m - 1, m); + CYBOZU_TEST_EQUAL(y, 1); +} + +CYBOZU_TEST_AUTO(andOr) +{ + Vint x("1223480928420984209849242"); + Vint y("29348220482094820948208420984209482048204289482"); + Vint z; + z = x & y; + CYBOZU_TEST_EQUAL(z, Vint("1209221003550923564822922")); + z = x | y; + CYBOZU_TEST_EQUAL(z, Vint("29348220482094820948208435244134352108849315802")); +#ifndef MCL_AVOID_EXCEPTION_TEST +// CYBOZU_TEST_EXCEPTION(Vint("-2") | Vint("5"), cybozu::Exception); +// CYBOZU_TEST_EXCEPTION(Vint("-2") & Vint("5"), cybozu::Exception); +#endif + x = 8; + x |= 7; + CYBOZU_TEST_EQUAL(x, 15); + x = 65536; + y = 8; + y &= x; + CYBOZU_TEST_EQUAL(y, 0); +} + +CYBOZU_TEST_AUTO(invMod) +{ + Vint m("100000000000000000039"); + for (int i = 1; i < 100; i++) { + Vint x = i; + Vint y; + Vint::invMod(y, x, m); + CYBOZU_TEST_EQUAL((y * x) % m, 1); + } +} + +CYBOZU_TEST_AUTO(isPrime) +{ + int primeTbl[] = { + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, + 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,197, 199, 211, + 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, + 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, + 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, + 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, + 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, + 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, + 941, 947, 953, 967, 971, 977, 983, 991, 997 + }; + typedef std::set<int> IntSet; + IntSet primes; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(primeTbl); i++) { + primes.insert(primeTbl[i]); + } + for (int i = 0; i < 1000; i++) { + bool ok = primes.find(i) != primes.end(); + bool my = Vint(i).isPrime(); + CYBOZU_TEST_EQUAL(ok, my); + } + const struct { + const char *n; + bool isPrime; + } tbl[] = { + { "65537", true }, + { "449065", false }, + { "488881", false }, + { "512461", false }, + { "18446744073709551629", true }, + { "18446744073709551631", false }, + { "0x10000000000000000000000000000000000000007", true }, + { "0x10000000000000000000000000000000000000009", false }, + { "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", true }, + { "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d", false }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint x(tbl[i].n); + CYBOZU_TEST_EQUAL(x.isPrime(), tbl[i].isPrime); + } +} + +CYBOZU_TEST_AUTO(gcd) +{ + Vint x = 12; + Vint y = 18; + Vint z; + Vint::gcd(z, x, y); + CYBOZU_TEST_EQUAL(z, 6); + Vint::lcm(z, x, y); + CYBOZU_TEST_EQUAL(z, 36); + Vint::lcm(x, x, y); + CYBOZU_TEST_EQUAL(x, 36); + Vint::lcm(x, x, x); + CYBOZU_TEST_EQUAL(x, 36); +} + +CYBOZU_TEST_AUTO(jacobi) +{ + const struct { + const char *m; + const char *n; + int ok; + } tbl[] = { + { "0", "1", 1 }, + { "1", "1", 1 }, + { "123", "1", 1 }, + { "45", "77", -1 }, + { "60", "121", 1 }, + { "12345672342342342342428", "923423423424753211", 1 }, + { "12345672342342342342428","34592342234235424753211", -1 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + int my = Vint::jacobi(Vint(tbl[i].m), Vint(tbl[i].n)); + CYBOZU_TEST_EQUAL(my, tbl[i].ok); + } +} + +CYBOZU_TEST_AUTO(bench) +{ + Vint x, y, z; + x.setStr("0x2523648240000001ba344d80000000086121000000000013a700000000000013"); + y.setStr("0x1802938109810498104982094820498203942804928049284092424902424243"); + + int N = 100000; + CYBOZU_BENCH_C("add", N, Vint::add, z, x, y); + CYBOZU_BENCH_C("sub", N, Vint::sub, z, x, y); + CYBOZU_BENCH_C("mul", N, Vint::mul, z, x, y); + CYBOZU_BENCH_C("div", N, Vint::div, y, z, x); + + const struct { + const char *x; + const char *y; + } tbl[] = { + { + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d" + }, + { + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", + }, + { + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", + }, + + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + x.setStr(tbl[i].x); + y.setStr(tbl[i].y); + CYBOZU_BENCH_C("fast div", N, Vint::div, z, x, y); +#ifndef DONT_USE_GMP_IN_TEST + { + mpz_class mx(tbl[i].x), my(tbl[i].y), mz; + CYBOZU_BENCH_C("gmp", N, mpz_div, mz.get_mpz_t(), mx.get_mpz_t(), my.get_mpz_t()); + } +#endif + } +} + +struct Seq { + const uint32_t *tbl; + size_t n; + size_t i, j; + Seq(const uint32_t *tbl, size_t n) : tbl(tbl), n(n), i(0), j(0) {} + bool next(uint64_t *v) + { + if (i == n) { + if (j == n - 1) return false; + i = 0; + j++; + } + *v = (uint64_t(tbl[j]) << 32) | tbl[i]; + i++; + return true; + } +}; + +#if MCL_SIZEOF_UNIT == 8 +CYBOZU_TEST_AUTO(divUnit) +{ + const uint32_t tbl[] = { + 0, 1, 3, + 0x7fffffff, + 0x80000000, + 0x80000001, + 0xffffffff, + }; + const size_t n = sizeof(tbl) / sizeof(tbl[0]); + Seq seq3(tbl, n); + uint64_t y; + while (seq3.next(&y)) { + if (y == 0) continue; + Seq seq2(tbl, n); + uint64_t r; + while (seq2.next(&r)) { + if (r >= y) break; + Seq seq1(tbl, n); + uint64_t q; + while (seq1.next(&q)) { + uint64_t x[2]; + x[0] = mcl::vint::mulUnit(&x[1], q, y); + mcl::vint::addu1(x, x, 2, r); + uint64_t Q, R; +//printf("q=0x%016llxull, r=0x%016llxull, y=0x%016llxull\n", (long long)q, (long long)r, (long long)y); + Q = mcl::vint::divUnit(&R, x[1], x[0], y); + CYBOZU_TEST_EQUAL(q, Q); + CYBOZU_TEST_EQUAL(r, R); + } + } + } +} + +void compareMod(const uint64_t *x, const uint64_t *p) +{ + uint64_t y1[4] = {}; + uint64_t y2[4] = {}; + mcl::vint::divNM((uint64_t*)0, 0, y1, x, 8, p, 4); + mcl::vint::mcl_fpDbl_mod_SECP256K1(y2, x, p); + CYBOZU_TEST_EQUAL_ARRAY(y1, y2, 4); +} +CYBOZU_TEST_AUTO(SECP256k1) +{ + const uint64_t F = uint64_t(-1); + const uint64_t p[4] = { uint64_t(0xfffffffefffffc2full), F, F, F }; + const uint64_t tbl[][8] = { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { F, F, F, F, F, F, F, F }, + { F, F, F, F, 1, 0, 0, 0 }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + const uint64_t *x = tbl[i]; + compareMod(x, p); + } + cybozu::XorShift rg; + for (size_t i = 0; i < 100; i++) { + uint64_t x[8]; + for (int j = 0; j < 8; j++) { + x[j] = rg(); + } + compareMod(x, p); + } +} +#endif diff --git a/vendor/github.com/dexon-foundation/mcl/test/window_method_test.cpp b/vendor/github.com/dexon-foundation/mcl/test/window_method_test.cpp new file mode 100644 index 000000000..1b0f702af --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/test/window_method_test.cpp @@ -0,0 +1,70 @@ +#include <cybozu/test.hpp> +#include <mcl/window_method.hpp> +#include <mcl/ec.hpp> +#include <mcl/fp.hpp> +#include <mcl/ecparam.hpp> + +CYBOZU_TEST_AUTO(ArrayIterator) +{ + const uint32_t in[2] = { 0x12345678, 0xabcdef89 }; + const size_t bitSize = 64; + for (size_t w = 1; w <= 32; w++) { + const uint32_t mask = uint32_t((uint64_t(1) << w) - 1); + mpz_class x; + mcl::gmp::setArray(x, in, 2); + mcl::fp::ArrayIterator<uint32_t> ai(in, bitSize, w); + size_t n = (bitSize + w - 1) / w; + for (size_t j = 0; j < n; j++) { + CYBOZU_TEST_ASSERT(ai.hasNext()); + uint32_t v = ai.getNext(); + CYBOZU_TEST_EQUAL(x & mask, v); + x >>= w; + } + CYBOZU_TEST_ASSERT(!ai.hasNext()); + } +} + +CYBOZU_TEST_AUTO(int) +{ + typedef mcl::FpT<> Fp; + typedef mcl::EcT<Fp> Ec; + const struct mcl::EcParam& para = mcl::ecparam::secp192k1; + Fp::init(para.p); + Ec::init(para.a, para.b); + const Fp x(para.gx); + const Fp y(para.gy); + const Ec P(x, y); + + typedef mcl::fp::WindowMethod<Ec> PW; + const size_t bitSize = 13; + Ec Q, R; + + for (size_t winSize = 10; winSize <= bitSize; winSize++) { + PW pw(P, bitSize, winSize); + for (int i = 0; i < (1 << bitSize); i++) { + pw.mul(Q, i); + Ec::mul(R, P, i); + CYBOZU_TEST_EQUAL(Q, R); + } + } + PW pw(P, para.bitSize, 10); + pw.mul(Q, -12345); + Ec::mul(R, P, -12345); + CYBOZU_TEST_EQUAL(Q, R); + mpz_class t(para.gx); + pw.mul(Q, t); + Ec::mul(R, P, t); + CYBOZU_TEST_EQUAL(Q, R); + t = -t; + pw.mul(Q, t); + Ec::mul(R, P, t); + CYBOZU_TEST_EQUAL(Q, R); + + pw.mul(Q, x); + Ec::mul(R, P, x); + CYBOZU_TEST_EQUAL(Q, R); + + pw.mul(Q, y); + Ec::mul(R, P, y); + CYBOZU_TEST_EQUAL(Q, R); +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 7cccb564a..f94f0e307 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -141,16 +141,16 @@ { "checksumSHA1": "In6vBHYUsX7DUIGiFN2hQggBgvI=", "path": "github.com/dexon-foundation/dexon-consensus/common", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "9uNk7orRE3xuTv2m/y6vO/4uDAg=", "path": "github.com/dexon-foundation/dexon-consensus/core", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, @@ -165,64 +165,64 @@ { "checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { - "checksumSHA1": "m5lUT04qSHKtFukvxjnFX5Jo2hI=", + "checksumSHA1": "4besQaa0rm8jRUAJjpEaLZ/ZOYs=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "3Ludp/1V4dMBZH/c1oIVjHj0CqY=", "path": "github.com/dexon-foundation/dexon-consensus/core/db", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "/OcEQKdtWDyRZibazIsAxJWHUyg=", "path": "github.com/dexon-foundation/dexon-consensus/core/syncer", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "zIgCdN4FJiAuPGMhB+/9YGK/Wgk=", "path": "github.com/dexon-foundation/dexon-consensus/core/types", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "lbG7yqVgzo2CV/CQPYjG78xp5jg=", "path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "1VsJIshz0loXnGwCtrMM8SuIo6Y=", "path": "github.com/dexon-foundation/dexon-consensus/core/utils", - "revision": "1d64520274d4e33b3038550083b78c5ebe1ea45d", - "revisionTime": "2019-04-10T14:52:57Z", + "revision": "269fed574986331e07bf931b2c9b1a495c40f8ac", + "revisionTime": "2019-04-11T06:42:07Z", "version": "single-chain", "versionExact": "single-chain" }, |