diff --git a/.gitignore b/.gitignore index 0048d5f58..1741710c6 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,9 @@ blsbench.* runbench runtest +runtest.log +runtest.trs +test-suite.log **/.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index df0abe13f..20b6d87fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,8 @@ ENDIF() project(BLS) -set(BUILD_BLS_TESTS 1 CACHE INTEGER "") -set(BUILD_BLS_BENCHMARKS 1 CACHE INTEGER "") +set(BUILD_BLS_TESTS "1" CACHE STRING "") +set(BUILD_BLS_BENCHMARKS "1" CACHE STRING "") message(STATUS "Build tests: ${BUILD_BLS_TESTS}") message(STATUS "Build benchmarks: ${BUILD_BLS_BENCHMARKS}") @@ -41,9 +41,9 @@ if(EMSCRIPTEN) # emscripten needs arch set to be none since it can't compile assembly set(ARCH "" CACHE STRING "") # emscripten is a 32 bit compiler - set(WSIZE 32 CACHE INTEGER "") + set(WSIZE "32" CACHE STRING "Relic - Processor word size") else() - set(WSIZE 64 CACHE INTEGER "") + set(WSIZE "64" CACHE STRING "Relic - Processor word size") endif() set(TIMER "CYCLE" CACHE STRING "") @@ -54,7 +54,7 @@ set(SHLIB "OFF" CACHE STRING "") set(MULTI "PTHREAD" CACHE STRING "") set(DOCUM "off" CACHE STRING "") -set(FP_PRIME 381 CACHE INTEGER "") +set(FP_PRIME "381" CACHE STRING "Relic - Prime modulus size") IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(SEED "UDEV" CACHE STRING "") @@ -68,16 +68,16 @@ ELSE() ENDIF() set(STBIN "OFF" CACHE STRING "") -set(FP_METHD "INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" CACHE STRING "") +set(FP_METHD "INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" CACHE STRING "") set(CFLAGS "-O3 -funroll-loops -fomit-frame-pointer" CACHE STRING "") set(FP_PMERS "off" CACHE STRING "") set(FPX_METHD "INTEG;INTEG;LAZYR" CACHE STRING "") set(EP_PLAIN "off" CACHE STRING "") set(EP_SUPER "off" CACHE STRING "") # Disable relic tests and benchmarks -set(TESTS 0 CACHE INTEGER "") -set(BENCH 0 CACHE INTEGER "") -set(QUIET 1 CACHE INTEGER "") +set(TESTS "0" CACHE STRING "Relic - Number of times each test is ran") +set(BENCH "0" CACHE STRING "Relic - Number of times each benchmark is ran") +set(QUIET "on" CACHE STRING "Relic - Build with printing disabled") set(PP_EXT "LAZYR" CACHE STRING "") set(PP_METHD "LAZYR;OATEP" CACHE STRING "") diff --git a/Makefile.am b/Makefile.am index f43e6527f..2f4f2045d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 AM_CPPFLAGS = $(SODIUM_CPPFLAGS) $(SODIUM_CFLAGS) +AM_CXXFLAGS = $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) LIBRELIC = librelic.la @@ -92,7 +93,8 @@ FP_SRCS = \ contrib/relic/src/fp/relic_fp_shift.c \ contrib/relic/src/fp/relic_fp_sqr.c \ contrib/relic/src/fp/relic_fp_srt.c \ - contrib/relic/src/fp/relic_fp_util.c + contrib/relic/src/fp/relic_fp_util.c \ + contrib/relic/src/fp/relic_fp_smb.c FPX_SRCS = \ contrib/relic/src/fpx/relic_fp2_mul.c \ @@ -176,7 +178,20 @@ EPX_SRCS = \ contrib/relic/src/epx/relic_ep2_neg.c \ contrib/relic/src/epx/relic_ep2_norm.c \ contrib/relic/src/epx/relic_ep2_pck.c \ - contrib/relic/src/epx/relic_ep2_util.c + contrib/relic/src/epx/relic_ep2_util.c \ + contrib/relic/src/epx/relic_ep4_add.c \ + contrib/relic/src/epx/relic_ep4_cmp.c \ + contrib/relic/src/epx/relic_ep4_curve.c \ + contrib/relic/src/epx/relic_ep4_dbl.c \ + contrib/relic/src/epx/relic_ep4_frb.c \ + contrib/relic/src/epx/relic_ep4_map.c \ + contrib/relic/src/epx/relic_ep4_mul.c \ + contrib/relic/src/epx/relic_ep4_mul_cof.c \ + contrib/relic/src/epx/relic_ep4_mul_fix.c \ + contrib/relic/src/epx/relic_ep4_mul_sim.c \ + contrib/relic/src/epx/relic_ep4_neg.c \ + contrib/relic/src/epx/relic_ep4_norm.c \ + contrib/relic/src/epx/relic_ep4_util.c EB_SRCS = \ contrib/relic/src/eb/relic_eb_add.c \ @@ -232,7 +247,11 @@ PP_SRCS = \ contrib/relic/src/pp/relic_pp_map_k12.c \ contrib/relic/src/pp/relic_pp_map_k48.c \ contrib/relic/src/pp/relic_pp_map_k54.c \ - contrib/relic/src/pp/relic_pp_norm.c + contrib/relic/src/pp/relic_pp_norm.c \ + contrib/relic/src/pp/relic_pp_add_k24.c \ + contrib/relic/src/pp/relic_pp_dbl_k24.c \ + contrib/relic/src/pp/relic_pp_exp_k24.c \ + contrib/relic/src/pp/relic_pp_map_k24.c PC_SRCS = \ contrib/relic/src/pc/relic_pc_core.c \ @@ -290,6 +309,7 @@ RELIC_SRCS += contrib/relic/src/low/gmp/relic_fp_mul_low.c RELIC_SRCS += contrib/relic/src/low/gmp/relic_fp_rdc_low.c RELIC_SRCS += contrib/relic/src/low/gmp/relic_fp_shift_low.c RELIC_SRCS += contrib/relic/src/low/gmp/relic_fp_sqr_low.c +RELIC_SRCS += contrib/relic/src/low/easy/relic_fp_smb_low.c endif if WITH_FPX @@ -368,6 +388,13 @@ RELIC_SRCS += contrib/relic/src/cp/relic_cp_bbs.c RELIC_SRCS += contrib/relic/src/cp/relic_cp_zss.c RELIC_SRCS += contrib/relic/src/cp/relic_cp_cmlhs.c RELIC_SRCS += contrib/relic/src/cp/relic_cp_mklhs.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_ers.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_etrs.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_lapsi.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_pcdel.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_pok.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_smlers.c +RELIC_SRCS += contrib/relic/src/cp/relic_cp_sok.c endif if WITH_BC diff --git a/configure.ac b/configure.ac index a8ac63456..fa6b2aab7 100644 --- a/configure.ac +++ b/configure.ac @@ -52,19 +52,19 @@ AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory], [nodefault]) dnl Libtool init checks. LT_INIT([pic-only]) -AC_PATH_TOOL(AR, ar) -AC_PATH_TOOL(RANLIB, ranlib) -AC_PATH_TOOL(STRIP, strip) +AC_PATH_TOOL([AR], [ar]) +AC_PATH_TOOL([RANLIB], [ranlib]) +AC_PATH_TOOL([STRIP], [strip]) AM_PROG_AS AC_ARG_ENABLE(tests, - AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]), + AS_HELP_STRING([--disable-tests], [do not compile tests (default is to compile)]), [use_tests=$enableval], [use_tests=yes]) AC_ARG_ENABLE(bench, - AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]), + AS_HELP_STRING([--disable-bench], [do not compile benchmarks (default is to compile)]), [use_bench=$enableval], [use_bench=yes]) @@ -172,7 +172,7 @@ case $host in AC_DEFINE([FP_QNRES], [], [Use -1 as quadratic non-residue.]) AC_DEFINE([OPSYS], [MACOSX], [Detected operation system.]) if test x$cross_compiling != xyes; then - AC_PATH_PROG([BREW],brew,) + AC_PATH_PROG([BREW], [brew], []) if test x$BREW != x; then dnl These Homebrew packages may be keg-only, meaning that they won't be found dnl in expected paths because they may conflict with system files. Ask @@ -239,11 +239,11 @@ case $host in esac if test x$use_pkgconfig = xyes; then - m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) + m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.])]) m4_ifdef([PKG_PROG_PKG_CONFIG], [ PKG_PROG_PKG_CONFIG if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) + AC_MSG_ERROR([pkg-config not found.]) fi ]) fi @@ -266,139 +266,154 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], CFLAGS="$saved_CFLAGS" ]) +if test "x$CXXFLAGS_overridden" = "xno"; then + AC_LANG_PUSH([C++]) + AX_CHECK_COMPILE_FLAG([-Wall], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wall"], [], []) + AX_CHECK_COMPILE_FLAG([-Wextra], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wextra"], [], []) + AX_CHECK_COMPILE_FLAG([-Wcast-align], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wcast-align"], [], []) + AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wredundant-decls"], [], []) + AX_CHECK_COMPILE_FLAG([-Wformat -Wformat-security], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wformat -Wformat-security"], [], []) + AX_CHECK_COMPILE_FLAG([-Wthread-safety-analysis], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wthread-safety-analysis"], [], []) + AX_CHECK_COMPILE_FLAG([-Wrange-loop-analysis], [WARN_CXXFLAGS="$WARN_CXXFLAGS -Wrange-loop-analysis"], [], []) + + AX_CHECK_COMPILE_FLAG([-Wunused-parameter], [NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-parameter"], [], []) + AX_CHECK_COMPILE_FLAG([-Wvla], [NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-vla"], [], []) + AC_LANG_POP([C++]) +fi + AC_LANG_PUSH([C]) -AX_CHECK_COMPILE_FLAG([-Wall],[WARN_CFLAGS="$WARN_CFLAGS -Wall"],,) -AX_CHECK_COMPILE_FLAG([-Wextra],[WARN_CFLAGS="$WARN_CFLAGS -Wextra"],,) -AX_CHECK_COMPILE_FLAG([-Wcast-align],[WARN_CFLAGS="$WARN_CFLAGS -Wcast-align"],,) -AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-unused-parameter"],,) -AX_CHECK_COMPILE_FLAG([-Wshadow],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-shadow"],,) -AX_CHECK_COMPILE_FLAG([-Wsign-compare],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-sign-compare"],,) -AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-strict-prototypes"],,) -AX_CHECK_COMPILE_FLAG([-Wunused-function],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-unused-function"],,) -AX_CHECK_COMPILE_FLAG([-Wlong-long],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-long-long"],,) +AX_CHECK_COMPILE_FLAG([-Wall], [WARN_CFLAGS="$WARN_CFLAGS -Wall"], [], []) +AX_CHECK_COMPILE_FLAG([-Wextra], [WARN_CFLAGS="$WARN_CFLAGS -Wextra"], [], []) +AX_CHECK_COMPILE_FLAG([-Wcast-align], [WARN_CFLAGS="$WARN_CFLAGS -Wcast-align"], [], []) +AX_CHECK_COMPILE_FLAG([-Wunused-parameter], [NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-unused-parameter"], [], []) +AX_CHECK_COMPILE_FLAG([-Wshadow], [NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-shadow"], [], []) +AX_CHECK_COMPILE_FLAG([-Wsign-compare], [NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-sign-compare"], [], []) +AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], [NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-strict-prototypes"], [], []) +AX_CHECK_COMPILE_FLAG([-Wunused-function], [NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-unused-function"], [], []) +AX_CHECK_COMPILE_FLAG([-Wlong-long], [NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-long-long"], [], []) AC_LANG_POP([C]) dnl set default settings for relic -AC_DEFINE([ALIGN], [1], [Byte boundary to align digit vectors.]) - -AC_DEFINE(WITH_BN,, Build multiple precision integer module.) -AC_DEFINE(WITH_DV,, Temporary double-precision digit vectors.) -AC_DEFINE(WITH_FP,, Build prime field module.) -AC_DEFINE(WITH_FPX,, Build prime field extension module.) -AC_DEFINE(WITH_FB,, Build binary field module.) -AC_DEFINE(WITH_FBX,, Build binary field extension module.) -AC_DEFINE(WITH_EP,, Build prime elliptic curve module.) -AC_DEFINE(WITH_EPX,, Build prime field extension elliptic curve module.) -AC_DEFINE(WITH_EB,, Build binary elliptic curve module.) -AC_DEFINE(WITH_ED,, Build elliptic Edwards curve module.) -AC_DEFINE(WITH_EC,, Build elliptic curve cryptography module.) -AC_DEFINE(WITH_PP,, Build pairings over prime curves module.) -AC_DEFINE(WITH_PC,, Build pairing-based cryptography module.) -AC_DEFINE(WITH_BC,, Build block ciphers.) -AC_DEFINE(WITH_MD,, Build hash functions.) -AC_DEFINE(WITH_CP,, Build cryptographic protocols.) -AC_DEFINE(WITH_MPC,, Build Multi-party computation primitives.) - -AC_DEFINE(BN_PRECI, 1024, Required precision in bits.) -AC_DEFINE(BN_KARAT, 0, Number of Karatsuba steps.) -AC_DEFINE(BN_MAGNI, [DOUBLE], Effective size of a multiple precision integer.) - -AC_DEFINE(BN_METHD, "COMBA;COMBA;MONTY;SLIDE;BASIC;BASIC", Multiple precision arithmetic method.) -AC_DEFINE(BN_MUL, COMBA, Chosen multiple precision multiplication method.) -AC_DEFINE(BN_SQR, COMBA, Chosen multiple precision multiplication method.) -AC_DEFINE(BN_MOD, MONTY, Chosen multiple precision modular reduction method.) -AC_DEFINE(BN_MXP, SLIDE, Chosen multiple precision modular exponentiation method.) -AC_DEFINE(BN_GCD, BASIC, Chosen multiple precision greatest common divisor method.) -AC_DEFINE(BN_GEN, BASIC, Chosen prime generation algorithm.) - -AC_DEFINE(FP_PRIME, 381, Prime field size in bits.) -AC_DEFINE(FP_METHD, "INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE", Prime field arithmetic method.) -AC_DEFINE(FP_KARAT, 0, Number of Karatsuba steps.) -AC_DEFINE(FP_WIDTH, 4, Width of window processing for exponentiation methods.) -AC_DEFINE(FP_ADD, INTEG, Chosen prime field multiplication method.) -AC_DEFINE(FP_MUL, INTEG, Chosen prime field multiplication method.) -AC_DEFINE(FP_SQR, INTEG, Chosen prime field multiplication method.) -AC_DEFINE(FP_RDC, MONTY, Chosen prime field reduction method.) -AC_DEFINE(FP_INV, LOWER, Chosen prime field inversion method.) -AC_DEFINE(FP_EXP, SLIDE, Chosen multiple precision modular exponentiation method.) - -AC_DEFINE(FPX_METHD, "INTEG;INTEG;LAZYR", Prime extension field arithmetic method.) -AC_DEFINE(FPX_QDR, INTEG, Chosen extension field arithmetic method.) -AC_DEFINE(FPX_CBC, INTEG, Chosen extension field arithmetic method.) -AC_DEFINE(FPX_RDC, LAZYR, Chosen extension field arithmetic method.) - -AC_DEFINE(FB_METHD, "LODAH;QUICK;QUICK;QUICK;QUICK;QUICK;EXGCD;SLIDE;QUICK", Binary field arithmetic method) -AC_DEFINE(FB_POLYN, 283, Irreducible polynomial size in bits.) -AC_DEFINE(FB_KARAT, 0, Number of Karatsuba levels.) -AC_DEFINE(FB_TRINO,, Prefer trinomials over pentanomials.) -AC_DEFINE(FB_PRECO,, Precompute multiplication table for sqrt(z).) -AC_DEFINE(FB_WIDTH, 4, Width of window processing for exponentiation methods.) -AC_DEFINE(FB_MUL, LODAH, Chosen binary field multiplication method.) -AC_DEFINE(FB_SQR, QUICK, Chosen binary field squaring method.) -AC_DEFINE(FB_RDC, QUICK, Chosen binary field modular reduction method.) -AC_DEFINE(FB_SRT, QUICK, Chosen binary field modular reduction method.) -AC_DEFINE(FB_TRC, QUICK, Chosen trace computation method.) -AC_DEFINE(FB_SLV, QUICK, Chosen method to solve a quadratic equation.) -AC_DEFINE(FB_INV, EXGCD, Chosen binary field inversion method.) -AC_DEFINE(FB_EXP, SLIDE, Chosen multiple precision modular exponentiation method.) -AC_DEFINE(FB_ITR, QUICK, Chosen method to solve a quadratic equation.) - -AC_DEFINE(EP_METHD, "PROJC;LWNAF;COMBS;INTER", Prime elliptic curve arithmetic method.) -AC_DEFINE(EP_ENDOM,, Support for prime curves with efficient endormorphisms.) -AC_DEFINE(EP_MIXED,, Use mixed coordinates.) -AC_DEFINE(EP_PRECO,, Build precomputation table for generator.) -AC_DEFINE(EP_CTMAP,, Enable isogeny map for SSWU map-to-curve.) -AC_DEFINE(EP_DEPTH, 4, Width of precomputation table for fixed point methods.) -AC_DEFINE(EP_WIDTH, 4, Width of window processing for unknown point methods.) -AC_DEFINE(EP_ADD, PROJC, Chosen prime elliptic curve coordinate method.) -AC_DEFINE(EP_MUL, LWNAF, Chosen prime elliptic curve point multiplication method.) -AC_DEFINE(EP_FIX, COMBS, Chosen prime elliptic curve point multiplication method.) -AC_DEFINE(EP_SIM, INTER, Chosen prime elliptic curve simulteanous point multiplication method.) - -AC_DEFINE(EB_METHD, "PROJC;LWNAF;COMBS;INTER", Binary elliptic curve arithmetic method.) -AC_DEFINE(EB_PLAIN,, Support for ordinary curves without endormorphisms.) -AC_DEFINE(EB_KBLTZ,, Support for Koblitz anomalous binary curves.) -AC_DEFINE(EB_MIXED,, Use mixed coordinates.) -AC_DEFINE(EB_PRECO,, Build precomputation table for generator.) -AC_DEFINE(EB_DEPTH, 4, Width of precomputation table for fixed point methods.) -AC_DEFINE(EB_WIDTH, 4, Width of window processing for unknown point methods.) -AC_DEFINE(EB_ADD, PROJC, Chosen binary elliptic curve coordinate method.) -AC_DEFINE(EB_MUL, LWNAF, Chosen binary elliptic curve point multiplication method.) -AC_DEFINE(EB_FIX, COMBS, Chosen binary elliptic curve point multiplication method.) -AC_DEFINE(EB_SIM, INTER, Chosen binary elliptic curve simulteanous point multiplication method.) - -AC_DEFINE(ED_METHD, "PROJC;LWNAF;COMBS;INTER", Edwards elliptic curve arithmetic method.) -AC_DEFINE(ED_PRECO,, Build precomputation table for generator.) -AC_DEFINE(ED_DEPTH, 4, Width of precomputation table for fixed point methods.) -AC_DEFINE(ED_WIDTH, 4, Width of window processing for unknown point methods.) -AC_DEFINE(ED_ADD, PROJC, Chosen binary elliptic curve coordinate method.) -AC_DEFINE(ED_MUL, LWNAF, Chosen prime elliptic twisted Edwards curve point multiplication method.) -AC_DEFINE(ED_FIX, COMBS, Chosen prime elliptic twisted Edwards curve point multiplication method.) -AC_DEFINE(ED_SIM, INTER, Chosen prime elliptic curve simulteanous point multiplication method.) - -AC_DEFINE(EC_METHD, "PRIME", Chosen elliptic curve cryptography method.) -AC_DEFINE(EC_CUR, PRIME, Chosen elliptic curve type.) - -AC_DEFINE(PP_METHD, "LAZYR;OATEP", Bilinear pairing method.) -AC_DEFINE(PP_EXT, LAZYR, Chosen extension field arithmetic method.) -AC_DEFINE(PP_MAP, OATEP, Chosen pairing method over prime elliptic curves.) - -AC_DEFINE(MD_METHD, "SH256", Choice of hash function.) -AC_DEFINE(MD_MAP, SH256, Chosen hash function.) - -AC_DEFINE(CP_CRT,, Support for faster CRT-based exponentiation in factoring-based cryptosystems.) -AC_DEFINE(CP_RSAPD, PKCS2, Chosen RSA padding method.) - -AC_DEFINE(ALLOC, AUTO, Chosen memory allocation policy.) -AC_DEFINE(RAND, HASHD, Chosen random generator.) -AC_DEFINE(MULTI, PTHREAD, Chosen multithreading API.) -AC_DEFINE(TIMER, CYCLE, Chosen timer.) - - -AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; LIBS="$LIBS -lgmp";])], AC_MSG_ERROR(gmp headers missing),) +AC_DEFINE([ALIGN], [1], [Byte boundary to align digit vectors.]) +AC_DEFINE([WITH_BN], [], [Build multiple precision integer module.]) +AC_DEFINE([WITH_DV], [], [Temporary double-precision digit vectors.]) +AC_DEFINE([WITH_FP], [], [Build prime field module.]) +AC_DEFINE([WITH_FPX], [], [Build prime field extension module.]) +AC_DEFINE([WITH_FB], [], [Build binary field module.]) +AC_DEFINE([WITH_FBX], [], [Build binary field extension module.]) +AC_DEFINE([WITH_EP], [], [Build prime elliptic curve module.]) +AC_DEFINE([WITH_EPX], [], [Build prime field extension elliptic curve module.]) +AC_DEFINE([WITH_EB], [], [Build binary elliptic curve module.]) +AC_DEFINE([WITH_ED], [], [Build elliptic Edwards curve module.]) +AC_DEFINE([WITH_EC], [], [Build elliptic curve cryptography module.]) +AC_DEFINE([WITH_PP], [], [Build pairings over prime curves module.]) +AC_DEFINE([WITH_PC], [], [Build pairing-based cryptography module.]) +AC_DEFINE([WITH_BC], [], [Build block ciphers.]) +AC_DEFINE([WITH_MD], [], [Build hash functions.]) +AC_DEFINE([WITH_CP], [], [Build cryptographic protocols.]) +AC_DEFINE([WITH_MPC], [], [Build Multi-party computation primitives.]) + +AC_DEFINE([BN_PRECI], [1024], [Required precision in bits.]) +AC_DEFINE([BN_KARAT], [0], [Number of Karatsuba steps.]) +AC_DEFINE([BN_MAGNI], [DOUBLE], [Effective size of a multiple precision integer.]) + +AC_DEFINE([BN_METHD], ["COMBA;COMBA;MONTY;SLIDE;BASIC;BASIC"], [Multiple precision arithmetic method.]) +AC_DEFINE([BN_MUL], [COMBA], [Chosen multiple precision multiplication method.]) +AC_DEFINE([BN_SQR], [COMBA], [Chosen multiple precision multiplication method.]) +AC_DEFINE([BN_MOD], [MONTY], [Chosen multiple precision modular reduction method.]) +AC_DEFINE([BN_MXP], [SLIDE], [Chosen multiple precision modular exponentiation method.]) +AC_DEFINE([BN_GCD], [BASIC], [Chosen multiple precision greatest common divisor method.]) +AC_DEFINE([BN_GEN], [BASIC], [Chosen prime generation algorithm.]) + +AC_DEFINE([FP_METHD], ["INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE"], [Prime field arithmetic method.]) +AC_DEFINE([FP_PRIME], [381], [Prime field size in bits.]) +AC_DEFINE([FP_KARAT], [0], [Number of Karatsuba steps.]) +AC_DEFINE([FP_WIDTH], [4], [Width of window processing for exponentiation methods.]) +AC_DEFINE([FP_ADD], [INTEG], [Chosen prime field multiplication method.]) +AC_DEFINE([FP_MUL], [INTEG], [Chosen prime field multiplication method.]) +AC_DEFINE([FP_SQR], [INTEG], [Chosen prime field multiplication method.]) +AC_DEFINE([FP_RDC], [MONTY], [Chosen prime field reduction method.]) +AC_DEFINE([FP_INV], [LOWER], [Chosen prime field inversion method.]) +AC_DEFINE([FP_SMB], [LOWER], [Chosen prime field Legendre symbol method.]) +AC_DEFINE([FP_EXP], [SLIDE], [Chosen multiple precision modular exponentiation method.]) + +AC_DEFINE([FPX_METHD], ["INTEG;INTEG;LAZYR"], [Prime extension field arithmetic method.]) +AC_DEFINE([FPX_QDR], [INTEG], [Chosen extension field arithmetic method.]) +AC_DEFINE([FPX_CBC], [INTEG], [Chosen extension field arithmetic method.]) +AC_DEFINE([FPX_RDC], [LAZYR], [Chosen extension field arithmetic method.]) + +AC_DEFINE([FB_METHD], ["LODAH;QUICK;QUICK;QUICK;QUICK;QUICK;EXGCD;SLIDE;QUICK"], [Binary field arithmetic method.]) +AC_DEFINE([FB_POLYN], [283], [Irreducible polynomial size in bits.]) +AC_DEFINE([FB_KARAT], [0], [Number of Karatsuba levels.]) +AC_DEFINE([FB_TRINO], [], [Prefer trinomials over pentanomials.]) +AC_DEFINE([FB_PRECO], [], [Precompute multiplication table for sqrt(z).]) +AC_DEFINE([FB_WIDTH], [4], [Width of window processing for exponentiation methods.]) +AC_DEFINE([FB_MUL], [LODAH], [Chosen binary field multiplication method.]) +AC_DEFINE([FB_SQR], [QUICK], [Chosen binary field squaring method.]) +AC_DEFINE([FB_RDC], [QUICK], [Chosen binary field modular reduction method.]) +AC_DEFINE([FB_SRT], [QUICK], [Chosen binary field modular reduction method.]) +AC_DEFINE([FB_TRC], [QUICK], [Chosen trace computation method.]) +AC_DEFINE([FB_SLV], [QUICK], [Chosen method to solve a quadratic equation.]) +AC_DEFINE([FB_INV], [EXGCD], [Chosen binary field inversion method.]) +AC_DEFINE([FB_EXP], [SLIDE], [Chosen multiple precision modular exponentiation method.]) +AC_DEFINE([FB_ITR], [QUICK], [Chosen method to solve a quadratic equation.]) + +AC_DEFINE([EP_METHD], ["PROJC;LWNAF;COMBS;INTER"], [Prime elliptic curve arithmetic method.]) +AC_DEFINE([EP_ENDOM], [], [Support for prime curves with efficient endormorphisms.]) +AC_DEFINE([EP_MIXED], [], [Use mixed coordinates.]) +AC_DEFINE([EP_PRECO], [], [Build precomputation table for generator.]) +AC_DEFINE([EP_CTMAP], [], [Enable isogeny map for SSWU map-to-curve.]) +AC_DEFINE([EP_DEPTH], [4], [Width of precomputation table for fixed point methods.]) +AC_DEFINE([EP_WIDTH], [4], [Width of window processing for unknown point methods.]) +AC_DEFINE([EP_ADD], [PROJC], [Chosen prime elliptic curve coordinate method.]) +AC_DEFINE([EP_MUL], [LWNAF], [Chosen prime elliptic curve point multiplication method.]) +AC_DEFINE([EP_FIX], [COMBS], [Chosen prime elliptic curve point multiplication method.]) +AC_DEFINE([EP_SIM], [INTER], [Chosen prime elliptic curve simulteanous point multiplication method.]) + +AC_DEFINE([EB_METHD], ["PROJC;LWNAF;COMBS;INTER"], [Binary elliptic curve arithmetic method.]) +AC_DEFINE([EB_PLAIN], [], [Support for ordinary curves without endormorphisms.]) +AC_DEFINE([EB_KBLTZ], [], [Support for Koblitz anomalous binary curves.]) +AC_DEFINE([EB_MIXED], [], [Use mixed coordinates.]) +AC_DEFINE([EB_PRECO], [], [Build precomputation table for generator.]) +AC_DEFINE([EB_DEPTH], [4], [Width of precomputation table for fixed point methods.]) +AC_DEFINE([EB_WIDTH], [4], [Width of window processing for unknown point methods.]) +AC_DEFINE([EB_ADD], [PROJC], [Chosen binary elliptic curve coordinate method.]) +AC_DEFINE([EB_MUL], [LWNAF], [Chosen binary elliptic curve point multiplication method.]) +AC_DEFINE([EB_FIX], [COMBS], [Chosen binary elliptic curve point multiplication method.]) +AC_DEFINE([EB_SIM], [INTER], [Chosen binary elliptic curve simulteanous point multiplication method.]) + +AC_DEFINE([ED_METHD], ["PROJC;LWNAF;COMBS;INTER"], [Edwards elliptic curve arithmetic method.]) +AC_DEFINE([ED_PRECO], [], [Build precomputation table for generator.]) +AC_DEFINE([ED_DEPTH], [4], [Width of precomputation table for fixed point methods.]) +AC_DEFINE([ED_WIDTH], [4], [Width of window processing for unknown point methods.]) +AC_DEFINE([ED_ADD], [PROJC], [Chosen binary elliptic curve coordinate method.]) +AC_DEFINE([ED_MUL], [LWNAF], [Chosen prime elliptic twisted Edwards curve point multiplication method.]) +AC_DEFINE([ED_FIX], [COMBS], [Chosen prime elliptic twisted Edwards curve point multiplication method.]) +AC_DEFINE([ED_SIM], [INTER], [Chosen prime elliptic curve simulteanous point multiplication method.]) + +AC_DEFINE([EC_METHD], ["PRIME"], [Chosen elliptic curve cryptography method.]) +AC_DEFINE([EC_CUR], [PRIME], [Chosen elliptic curve type.]) + +AC_DEFINE([PP_METHD], ["LAZYR;OATEP"], [Bilinear pairing method.]) +AC_DEFINE([PP_EXT], [LAZYR], [Chosen extension field arithmetic method.]) +AC_DEFINE([PP_MAP], [OATEP], [Chosen pairing method over prime elliptic curves.]) + +AC_DEFINE([MD_METHD], ["SH256"], [Choice of hash function.]) +AC_DEFINE([MD_MAP], [SH256], [Chosen hash function.]) + +AC_DEFINE([CP_CRT], [], [Support for faster CRT-based exponentiation in factoring-based cryptosystems.]) +AC_DEFINE([CP_RSAPD], [PKCS2], [Chosen RSA padding method.]) + +AC_DEFINE([ALLOC], [AUTO], [Chosen memory allocation policy.]) +AC_DEFINE([RAND], [HASHD], [Chosen random generator.]) +AC_DEFINE([MULTI], [PTHREAD], [Chosen multithreading API.]) +AC_DEFINE([TIMER], [CYCLE], [Chosen timer.]) + + +AC_CHECK_HEADER([gmp.h], [AC_CHECK_LIB([gmp], [__gmpz_init], [has_gmp=yes; LIBS="$LIBS -lgmp";])], [AC_MSG_ERROR([gmp headers missing])],[]) if test x$has_gmp = xyes; then - AC_DEFINE(ARITH, GMP, Arithmetic backend.) + AC_DEFINE([ARITH], [GMP], [Arithmetic backend.]) fi if test x$use_pkgconfig = xyes; then @@ -406,18 +421,18 @@ if test x$use_pkgconfig = xyes; then m4_ifdef( [PKG_CHECK_MODULES], [ - PKG_CHECK_MODULES([SODIUM], [libsodium],, [AC_MSG_ERROR(libsodium not found.)]) + PKG_CHECK_MODULES([SODIUM], [libsodium], [], [AC_MSG_ERROR(libsodium not found.)]) ] ) else - AC_CHECK_HEADER([sodium/core.h],, AC_MSG_ERROR(libsodium headers missing),) - AC_CHECK_LIB([sodium],[main],SODIUM_LIBS=-lsodium, AC_MSG_ERROR(libsodium missing)) + AC_CHECK_HEADER([sodium/core.h], [], [AC_MSG_ERROR([libsodium headers missing])], []) + AC_CHECK_LIB([sodium], [main], [SODIUM_LIBS=-lsodium], [AC_MSG_ERROR([libsodium missing])]) fi dnl Check for pthread compile/link requirements AX_PTHREAD -AC_SEARCH_LIBS([clock_gettime],[rt]) +AC_SEARCH_LIBS([clock_gettime], [rt]) AC_MSG_CHECKING([whether to build runtest]) if test x$use_tests = xyes; then @@ -437,23 +452,23 @@ else BUILD_BENCH="" fi -AM_CONDITIONAL(WITH_BN, test 1 -eq 1) -AM_CONDITIONAL(WITH_FP, test 1 -eq 1) -AM_CONDITIONAL(WITH_FPX, test 1 -eq 1) -AM_CONDITIONAL(WITH_FB, test 1 -eq 1) -AM_CONDITIONAL(WITH_EP, test 1 -eq 1) -AM_CONDITIONAL(WITH_EPX, test 1 -eq 1) -AM_CONDITIONAL(WITH_EB, test 1 -eq 1) -AM_CONDITIONAL(WITH_ED, test 1 -eq 1) -AM_CONDITIONAL(WITH_EC, test 1 -eq 1) -AM_CONDITIONAL(WITH_PP, test 1 -eq 1) -AM_CONDITIONAL(WITH_PC, test 1 -eq 1) -AM_CONDITIONAL(WITH_BC, test 1 -eq 1) -AM_CONDITIONAL(WITH_MD, test 1 -eq 1) -AM_CONDITIONAL(WITH_CP, test 1 -eq 1) -AM_CONDITIONAL(WITH_MPC, test 1 -eq 1) -AM_CONDITIONAL(WITH_DV, test 1 -eq 1) -AM_CONDITIONAL(WITH_FBX, test 1 -eq 1) +AM_CONDITIONAL([WITH_BN], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_FP], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_FPX], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_FB], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_EP], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_EPX], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_EB], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_ED], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_EC], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_PP], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_PC], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_BC], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_MD], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_CP], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_MPC], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_DV], [test 1 -eq 1]) +AM_CONDITIONAL([WITH_FBX], [test 1 -eq 1]) AM_CONDITIONAL([USE_TESTS], [test x$BUILD_TEST = xyes]) AM_CONDITIONAL([USE_BENCH], [test x$BUILD_BENCH = xyes]) AC_SUBST(CPU_ARCH) @@ -463,6 +478,8 @@ AC_SUBST(SODIUM_LIBS) AC_SUBST(RELIC_CPPFLAGS) AC_SUBST(WARN_CFLAGS) AC_SUBST(NOWARN_CFLAGS) +AC_SUBST(WARN_CXXFLAGS) +AC_SUBST(NOWARN_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) diff --git a/contrib/relic/.editorconfig b/contrib/relic/.editorconfig new file mode 100644 index 000000000..bdc049fe5 --- /dev/null +++ b/contrib/relic/.editorconfig @@ -0,0 +1,7 @@ +# top-most EditorConfig file +root = true + +# 4 space indentation +[*.{cmake,c,h}] +indent_style = tab +indent_size = 4 diff --git a/contrib/relic/.github/workflows/16bit.yml b/contrib/relic/.github/workflows/16bit.yml new file mode 100644 index 000000000..8633cd322 --- /dev/null +++ b/contrib/relic/.github/workflows/16bit.yml @@ -0,0 +1,48 @@ +name: Basic configuration (16 bits) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DWSIZE=16 -DSEED= -DBENCH=0 -DTESTS=10 .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.github/workflows/32bit.yml b/contrib/relic/.github/workflows/32bit.yml new file mode 100644 index 000000000..bb225ab80 --- /dev/null +++ b/contrib/relic/.github/workflows/32bit.yml @@ -0,0 +1,97 @@ +name: Basic configuration (32 bits) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { + name: "Windows Latest - MSVC", + artifact: "windows-msvc.tar.xz", + os: windows-latest, + cc: "cl", + } + - { + name: "Windows Latest - MinGW", + artifact: "windows-mingw.tar.xz", + os: windows-latest, + cc: "gcc" + } + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + - { + name: "MacOS Latest", + os: macos-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Set Windows enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'cl') }} + uses: ilammy/msvc-dev-cmd@v1 + + - name: Set MinGW enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + git + base-devel + gcc + cmake + update: true + + - name: Run CMake (Win) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'cl') }} + shell: bash + run: | + mkdir build + cd build + cmake -DWSIZE=32 -DSEED= -DBENCH=0 -G "NMake Makefiles" .. + + - name: Run CMake (MingW) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + shell: bash + run: | + mkdir build + cd build + cmake -DWSIZE=32 -DSEED= -DBENCH=0 -G "MinGW Makefiles" .. + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DWSIZE=32 -DSEED= -DBENCH=0 .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.github/workflows/8bit.yml b/contrib/relic/.github/workflows/8bit.yml new file mode 100644 index 000000000..0765607ec --- /dev/null +++ b/contrib/relic/.github/workflows/8bit.yml @@ -0,0 +1,48 @@ +name: Basic configuration (8 bits) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DWSIZE=8 -DSEED= -DBENCH=0 -DTESTS=10 .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.github/workflows/bls12-381.yml b/contrib/relic/.github/workflows/bls12-381.yml new file mode 100644 index 000000000..e99f190ac --- /dev/null +++ b/contrib/relic/.github/workflows/bls12-381.yml @@ -0,0 +1,86 @@ +name: BLS12-381 configuration (ASM) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + #- { + #name: "Windows Latest - MinGW", + #artifact: "windows-mingw.tar.xz", + #os: windows-latest, + #cc: "gcc" + #} + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Install Linux Dependencies + if: runner.os == 'Linux' + run: sudo apt install libgmp-dev + + - name: Install MacOS Dependencies + if: runner.os == 'MacOS' + run: brew install gmp + + - name: Set MinGW enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + git + base-devel + gcc + cmake + gmp + update: true + + - name: Run CMake (MingW) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + shell: bash + run: | + mkdir build + cd build + cmake -G "MinGW Makefiles" .. + cmake -DSEED= -DBENCH=0 -DSTBIN=off -DRAND=HASHD .. + ../preset/x64-pbc-bls12-381.sh .. + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DSEED= -DBENCH=0 .. + ../preset/x64-pbc-bls12-381.sh .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.github/workflows/push.yml b/contrib/relic/.github/workflows/easy.yml similarity index 93% rename from contrib/relic/.github/workflows/push.yml rename to contrib/relic/.github/workflows/easy.yml index 0977f5646..761f07f33 100644 --- a/contrib/relic/.github/workflows/push.yml +++ b/contrib/relic/.github/workflows/easy.yml @@ -1,6 +1,12 @@ -name: Continuous Integration +name: Basic configuration -on: [push, pull_request] +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches jobs: build: @@ -42,10 +48,6 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Install Linux Dependencies - if: runner.os == 'Linux' - run: sudo apt install libgmp-dev - - name: Set Windows enviroment if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'cl') }} uses: ilammy/msvc-dev-cmd@v1 diff --git a/contrib/relic/.github/workflows/gmp-sec.yml b/contrib/relic/.github/workflows/gmp-sec.yml new file mode 100644 index 000000000..2cd342099 --- /dev/null +++ b/contrib/relic/.github/workflows/gmp-sec.yml @@ -0,0 +1,88 @@ +name: Faster configuration (constant-time GMP) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { + name: "Windows Latest - MinGW", + artifact: "windows-mingw.tar.xz", + os: windows-latest, + cc: "gcc" + } + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + - { + name: "MacOS Latest", + os: macos-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Install Linux Dependencies + if: runner.os == 'Linux' + run: sudo apt install libgmp-dev + + - name: Install MacOS Dependencies + if: runner.os == 'MacOS' + run: brew install gmp + + - name: Set MinGW enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + git + base-devel + gcc + cmake + gmp + update: true + + - name: Run CMake (MingW) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + shell: bash + run: | + mkdir build + cd build + cmake -DSEED= -DBENCH=0 -DARITH=gmp-sec -G "MinGW Makefiles" .. + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DSEED= -DBENCH=0 -DARITH=gmp-sec .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.github/workflows/gmp.yml b/contrib/relic/.github/workflows/gmp.yml new file mode 100644 index 000000000..618e05da3 --- /dev/null +++ b/contrib/relic/.github/workflows/gmp.yml @@ -0,0 +1,88 @@ +name: Faster configuration (GMP) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { + name: "Windows Latest - MinGW", + artifact: "windows-mingw.tar.xz", + os: windows-latest, + cc: "gcc" + } + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + - { + name: "MacOS Latest", + os: macos-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Install Linux Dependencies + if: runner.os == 'Linux' + run: sudo apt install libgmp-dev + + - name: Install MacOS Dependencies + if: runner.os == 'MacOS' + run: brew install gmp + + - name: Set MinGW enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + git + base-devel + gcc + cmake + gmp + update: true + + - name: Run CMake (MingW) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + shell: bash + run: | + mkdir build + cd build + cmake -DSEED= -DBENCH=0 -DARITH=gmp -G "MinGW Makefiles" .. + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DSEED= -DBENCH=0 -DARITH=gmp .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.github/workflows/label.yml b/contrib/relic/.github/workflows/label.yml new file mode 100644 index 000000000..213531326 --- /dev/null +++ b/contrib/relic/.github/workflows/label.yml @@ -0,0 +1,97 @@ +name: Basic configuration (LABEL) + +on: + push: + branches: + - '**' # all branches + pull_request: + branches: + - '**' # all branches + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { + name: "Windows Latest - MSVC", + artifact: "windows-msvc.tar.xz", + os: windows-latest, + cc: "cl", + } + - { + name: "Windows Latest - MinGW", + artifact: "windows-mingw.tar.xz", + os: windows-latest, + cc: "gcc" + } + - { + name: "Ubuntu Latest - GCC", + artifact: "linux-gcc.tar.xz", + os: ubuntu-latest, + cc: "gcc", + } + - { + name: "Ubuntu Latest - Clang", + artifact: "linux-clang.tar.xz", + os: ubuntu-latest, + cc: "clang", + } + - { + name: "MacOS Latest", + os: macos-latest, + cc: "clang", + } + steps: + - uses: actions/checkout@v2 + + - name: Set Windows enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'cl') }} + uses: ilammy/msvc-dev-cmd@v1 + + - name: Set MinGW enviroment + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + git + base-devel + gcc + cmake + update: true + + - name: Run CMake (Win) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'cl') }} + shell: bash + run: | + mkdir build + cd build + cmake -DLABEL=default -DSEED= -DBENCH=0 -G "NMake Makefiles" .. + + - name: Run CMake (MingW) + if: ${{ (runner.os == 'Windows') && (matrix.config.cc == 'gcc') }} + shell: bash + run: | + mkdir build + cd build + cmake -DLABEL=default -DSEED= -DBENCH=0 -G "MinGW Makefiles" .. + + - name: Run CMake (standard) + if: ${{ !(runner.os == 'Windows') }} + shell: bash + run: | + mkdir build + cd build + cmake -DCMAKE_C_COMPILER=${{ matrix.config.cc }} -DSEED= -DBENCH=0 .. + + - name: CMake Build + run: cmake --build build + + - name: CMake Test + run: | + cd build + ctest --verbose . diff --git a/contrib/relic/.travis.yml b/contrib/relic/.travis.yml index 1f98558c5..330d99299 100644 --- a/contrib/relic/.travis.yml +++ b/contrib/relic/.travis.yml @@ -20,9 +20,9 @@ env: # Build for Edwards curves - CONFIG="-DSEED= -DBENCH=0 -DFP_PRIME=255 -FP_QNRES=off -DEC_METHD=EDDIE -DED_METHD='PROJC;LWNAF;LWNAF;BASIC' -DWITH='BN;DV;MD;FP;ED,EC;CP'" TEST="-E test_fpx" # Build Supersingular curves - - CONFIG="-DSEED= -DBENCH=0 -DBN_PRECI=1536 -DFP_PRIME=1536 -FP_QNRES=on" TEST="-E test_fpx" + - CONFIG="-DSEED= -DBENCH=0 -DBN_PRECI=1536 -DFP_PRIME=1536 -DFP_QNRES=on" TEST="-E test_fpx" # Build BLS12-381 - - CONFIG="-DWSIZE=64 -DARITH=x64-asm-382 -DFP_PRIME=381 -DFP_PMERS=off -DFP_QNRES=on" + - CONFIG="-DWSIZE=64 -DARITH=x64-asm-6l -DFP_PRIME=381 -DFP_PMERS=off -DFP_QNRES=on" # Build with Address Sanityzer - CONFIG="-DAUSAN=on -DSEED= -DBENCH=0" TEST="" diff --git a/contrib/relic/CMakeLists.txt b/contrib/relic/CMakeLists.txt index 0348ccc7a..4997612b9 100644 --- a/contrib/relic/CMakeLists.txt +++ b/contrib/relic/CMakeLists.txt @@ -1,12 +1,11 @@ cmake_minimum_required(VERSION 3.1) -set (CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type.") if(NOT ${CMAKE_VERSION} VERSION_LESS "3.1") cmake_policy(SET CMP0054 NEW) endif() project(RELIC C CXX) set(PROJECT_VERSION_MAJOR "0") -set(PROJECT_VERSION_MINOR "5") +set(PROJECT_VERSION_MINOR "6") set(PROJECT_VERSION_PATCH "0") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(VERSION ${PROJECT_VERSION}) diff --git a/contrib/relic/README.md b/contrib/relic/README.md index 0f76be350..c4f3f258b 100644 --- a/contrib/relic/README.md +++ b/contrib/relic/README.md @@ -1,12 +1,17 @@ -![](https://github.com/relic-toolkit/relic/blob/master/art/rlc_logo.png) +![](https://github.com/relic-toolkit/relic/blob/c56f2cc3529da824e76974ccb5d74cb4ff6cdec7/art/rlc_logo.png) ===== [![Project stats](https://www.openhub.net/p/relic-toolkit/widgets/project_thin_badge.gif)](https://www.openhub.net/p/relic-toolkit) -[![Build Status](https://travis-ci.org/relic-toolkit/relic.svg?branch=main)](https://travis-ci.org/relic-toolkit/relic) [![Code Quality: Cpp](https://img.shields.io/lgtm/grade/cpp/g/relic-toolkit/relic.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/relic-toolkit/relic/context:cpp) [![Total Alerts](https://img.shields.io/lgtm/alerts/g/relic-toolkit/relic.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/relic-toolkit/relic/alerts) -RELIC is a modern cryptographic meta-toolkit with emphasis on efficiency and flexibility. RELIC can be used to build efficient and usable cryptographic toolkits tailored for specific security levels and algorithmic choices. +[![Travis Status](https://travis-ci.org/relic-toolkit/relic.svg?branch=main)](https://travis-ci.org/relic-toolkit/relic) +[![GHA Status](https://github.com/relic-toolkit/relic/actions/workflows/easy.yml/badge.svg)](https://github.com/relic-toolkit/relic/actions/workflows/easy.yml) +[![GHA Status](https://github.com/relic-toolkit/relic/actions/workflows/gmp.yml/badge.svg)](https://github.com/relic-toolkit/relic/actions/workflows/gmp.yml) +[![GHA Status](https://github.com/relic-toolkit/relic/actions/workflows/bls12-381.yml/badge.svg)](https://github.com/relic-toolkit/relic/actions/workflows/bls12-381.yml) + + +RELIC is a modern research-oriented cryptographic meta-toolkit with emphasis on efficiency and flexibility. RELIC can be used to build efficient and usable cryptographic toolkits tailored for specific security levels and algorithmic choices. ### Goals diff --git a/contrib/relic/bench/bench_bn.c b/contrib/relic/bench/bench_bn.c index b9acffcf8..63b6b662c 100644 --- a/contrib/relic/bench/bench_bn.c +++ b/contrib/relic/bench/bench_bn.c @@ -51,7 +51,7 @@ static void memory(void) { bn_new(a[i]); bn_clean(a[i]); } - BENCH_FEW("bn_init", bn_init(a[i], RLC_BN_DIGS), 1); + BENCH_FEW("bn_make", bn_make(a[i], RLC_BN_DIGS), 1); for (int i = 0; i < BENCH; i++) { bn_free(a[i]); } @@ -281,21 +281,21 @@ static void util(void) { } static void arith(void) { - bn_t a, b, c, d, e; + bn_t a, b, c, d[2]; dig_t f; int len; bn_null(a); bn_null(b); bn_null(c); - bn_null(d); - bn_null(e); + bn_null(d[0]); + bn_null(d[1]); bn_new(a); bn_new(b); bn_new(c); - bn_new(d); - bn_new(e); + bn_new(d[0]); + bn_new(d[1]); BENCH_RUN("bn_add") { bn_rand(a, RLC_POS, RLC_BN_BITS); @@ -433,7 +433,7 @@ static void arith(void) { BENCH_RUN("bn_div_rem") { bn_rand(a, RLC_POS, 2 * RLC_BN_BITS - RLC_DIG / 2); bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_div_rem(c, d, a, b)); + BENCH_ADD(bn_div_rem(c, d[0], a, b)); } BENCH_END; @@ -483,9 +483,9 @@ static void arith(void) { if (bn_is_even(b)) { bn_add_dig(b, b, 1); } - bn_mod_pre(d, b); + bn_mod_pre(d[0], b); #endif - BENCH_ADD(bn_mod(c, a, b, d)); + BENCH_ADD(bn_mod(c, a, b, d[0])); } BENCH_END; @@ -501,7 +501,7 @@ static void arith(void) { #if BN_MOD == BARRT || !defined(STRIP) BENCH_RUN("bn_mod_pre_barrt") { bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_mod_pre_barrt(d, b)); + BENCH_ADD(bn_mod_pre_barrt(d[0], b)); } BENCH_END; #endif @@ -510,8 +510,8 @@ static void arith(void) { BENCH_RUN("bn_mod_barrt") { bn_rand(a, RLC_POS, 2 * RLC_BN_BITS - RLC_DIG / 2); bn_rand(b, RLC_POS, RLC_BN_BITS); - bn_mod_pre_barrt(d, b); - BENCH_ADD(bn_mod_barrt(c, a, b, d)); + bn_mod_pre_barrt(d[0], b); + BENCH_ADD(bn_mod_barrt(c, a, b, d[0])); } BENCH_END; #endif @@ -522,7 +522,7 @@ static void arith(void) { if (bn_is_even(b)) { bn_add_dig(b, b, 1); } - BENCH_ADD(bn_mod_pre_monty(d, b)); + BENCH_ADD(bn_mod_pre_monty(d[0], b)); } BENCH_END; @@ -544,8 +544,8 @@ static void arith(void) { bn_add_dig(b, b, 1); } bn_mod(a, a, b); - bn_mod_pre_monty(d, b); - BENCH_ADD(bn_mod_monty(c, a, b, d)); + bn_mod_pre_monty(d[0], b); + BENCH_ADD(bn_mod_monty(c, a, b, d[0])); } BENCH_END; @@ -557,8 +557,8 @@ static void arith(void) { bn_add_dig(b, b, 1); } bn_mod(a, a, b); - bn_mod_pre_monty(d, b); - BENCH_ADD(bn_mod_monty_basic(c, a, b, d)); + bn_mod_pre_monty(d[0], b); + BENCH_ADD(bn_mod_monty_basic(c, a, b, d[0])); } BENCH_END; #endif @@ -571,8 +571,8 @@ static void arith(void) { bn_add_dig(b, b, 1); } bn_mod(a, a, b); - bn_mod_pre_monty(d, b); - BENCH_ADD(bn_mod_monty_comba(c, a, b, d)); + bn_mod_pre_monty(d[0], b); + BENCH_ADD(bn_mod_monty_comba(c, a, b, d[0])); } BENCH_END; #endif @@ -584,7 +584,7 @@ static void arith(void) { bn_add_dig(b, b, 1); } bn_mod(a, a, b); - bn_mod_pre_monty(d, b); + bn_mod_pre_monty(d[0], b); BENCH_ADD(bn_mod_monty_back(c, c, b)); } BENCH_END; @@ -596,7 +596,7 @@ static void arith(void) { bn_set_2b(b, RLC_BN_BITS); bn_rand(c, RLC_POS, RLC_DIG); bn_sub(b, b, c); - BENCH_ADD(bn_mod_pre_pmers(d, b)); + BENCH_ADD(bn_mod_pre_pmers(d[0], b)); } BENCH_END; @@ -605,8 +605,8 @@ static void arith(void) { bn_set_2b(b, RLC_BN_BITS); bn_rand(c, RLC_POS, RLC_DIG); bn_sub(b, b, c); - bn_mod_pre_pmers(d, b); - BENCH_ADD(bn_mod_pmers(c, a, b, d)); + bn_mod_pre_pmers(d[0], b); + BENCH_ADD(bn_mod_pmers(c, a, b, d[0])); } BENCH_END; #endif @@ -656,8 +656,8 @@ static void arith(void) { BENCH_RUN("bn_mxp_dig") { bn_rand(a, RLC_POS, RLC_BN_BITS); - bn_rand(d, RLC_POS, RLC_DIG); - bn_get_dig(&f, d); + bn_rand(d[0], RLC_POS, RLC_DIG); + bn_get_dig(&f, d[0]); BENCH_ADD(bn_mxp_dig(c, a, f, b)); } BENCH_END; @@ -713,7 +713,7 @@ static void arith(void) { BENCH_RUN("bn_gcd_ext") { bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_gcd_ext(c, d, e, a, b)); + BENCH_ADD(bn_gcd_ext(c, d[0], d[1], a, b)); } BENCH_END; @@ -721,7 +721,7 @@ static void arith(void) { BENCH_RUN("bn_gcd_ext_basic") { bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_gcd_ext_basic(c, d, e, a, b)); + BENCH_ADD(bn_gcd_ext_basic(c, d[0], d[1], a, b)); } BENCH_END; #endif @@ -730,7 +730,7 @@ static void arith(void) { BENCH_RUN("bn_gcd_ext_lehme") { bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_gcd_ext_lehme(c, d, e, a, b)); + BENCH_ADD(bn_gcd_ext_lehme(c, d[0], d[1], a, b)); } BENCH_END; #endif @@ -739,7 +739,7 @@ static void arith(void) { BENCH_RUN("bn_gcd_ext_stein") { bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_gcd_ext_stein(c, d, e, a, b)); + BENCH_ADD(bn_gcd_ext_stein(c, d[0], d[1], a, b)); } BENCH_END; #endif @@ -747,14 +747,14 @@ static void arith(void) { BENCH_RUN("bn_gcd_ext_mid") { bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_gcd_ext_mid(c, c, d, d, a, b)); + BENCH_ADD(bn_gcd_ext_mid(c, c, d[0], d[1], a, b)); } BENCH_END; BENCH_RUN("bn_gcd_ext_dig") { bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_DIG); - BENCH_ADD(bn_gcd_ext_dig(c, d, e, a, b->dp[0])); + BENCH_ADD(bn_gcd_ext_dig(c, d[0], d[1], a, b->dp[0])); } BENCH_END; @@ -769,7 +769,7 @@ static void arith(void) { BENCH_RUN("bn_smb_leg") { bn_rand(a, RLC_POS, RLC_BN_BITS); - BENCH_ADD(bn_smb_leg(c, a, b)); + BENCH_ADD(bn_smb_leg(a, b)); } BENCH_END; @@ -779,7 +779,7 @@ static void arith(void) { if (bn_is_even(b)) { bn_add_dig(b, b, 1); } - BENCH_ADD(bn_smb_jac(c, a, b)); + BENCH_ADD(bn_smb_jac(a, b)); } BENCH_END; @@ -812,6 +812,14 @@ static void arith(void) { } BENCH_END; + /* It should be the case that a is prime here. */ + BENCH_RUN("bn_mod_inv_sim (2)") { + bn_rand(d[0], RLC_POS, RLC_BN_BITS); + bn_rand(d[1], RLC_POS, RLC_BN_BITS); + BENCH_ADD(bn_mod_inv_sim(d, d, a, 2)); + } + BENCH_END; + bn_rand(a, RLC_POS, RLC_BN_BITS); BENCH_ONE("bn_factor", bn_factor(c, a), 1); @@ -838,7 +846,7 @@ static void arith(void) { BENCH_END; BENCH_RUN("bn_rec_naf") { - signed char naf[RLC_BN_BITS + 1]; + int8_t naf[RLC_BN_BITS + 1]; int len; bn_rand(a, RLC_POS, RLC_BN_BITS); BENCH_ADD((len = RLC_BN_BITS + 1, bn_rec_naf(naf, &len, a, 4))); @@ -848,10 +856,10 @@ static void arith(void) { #if defined(WITH_EB) && defined(EB_KBLTZ) && (EB_MUL == LWNAF || EB_MUL == RWNAF || EB_FIX == LWNAF || EB_SIM == INTER || !defined(STRIP)) if (eb_param_set_any_kbltz() == RLC_OK) { BENCH_RUN("bn_rec_tnaf") { - signed char tnaf[RLC_FB_BITS + 8]; + int8_t tnaf[RLC_FB_BITS + 8]; int len = RLC_BN_BITS + 1; - eb_curve_get_ord(e); - bn_rand_mod(a, e); + eb_curve_get_ord(d[1]); + bn_rand_mod(a, d[1]); if (eb_curve_opt_a() == RLC_ZERO) { BENCH_ADD((len = RLC_FB_BITS + 8, bn_rec_tnaf(tnaf, &len, a, -1, RLC_FB_BITS, 4))); } else { @@ -861,9 +869,9 @@ static void arith(void) { BENCH_END; BENCH_RUN("bn_rec_rtnaf") { - signed char tnaf[RLC_FB_BITS + 8]; - eb_curve_get_ord(e); - bn_rand_mod(a, e); + int8_t tnaf[RLC_FB_BITS + 8]; + eb_curve_get_ord(d[1]); + bn_rand_mod(a, d[1]); if (eb_curve_opt_a() == RLC_ZERO) { BENCH_ADD((len = RLC_FB_BITS + 8, bn_rec_rtnaf(tnaf, &len, a, -1, RLC_FB_BITS, 4))); } else { @@ -875,7 +883,7 @@ static void arith(void) { #endif BENCH_RUN("bn_rec_reg") { - signed char naf[RLC_BN_BITS + 1]; + int8_t naf[RLC_BN_BITS + 1]; int len = RLC_BN_BITS + 1; bn_rand(a, RLC_POS, RLC_BN_BITS); BENCH_ADD((len = RLC_BN_BITS + 1, bn_rec_reg(naf, &len, a, RLC_BN_BITS, 4))); @@ -883,7 +891,7 @@ static void arith(void) { BENCH_END; BENCH_RUN("bn_rec_jsf") { - signed char jsf[2 * (RLC_BN_BITS + 1)]; + int8_t jsf[2 * (RLC_BN_BITS + 1)]; bn_rand(a, RLC_POS, RLC_BN_BITS); bn_rand(b, RLC_POS, RLC_BN_BITS); BENCH_ADD((len = 2 * (RLC_BN_BITS + 1), bn_rec_jsf(jsf, &len, a, b))); @@ -903,9 +911,9 @@ static void arith(void) { bn_rand(a, RLC_POS, RLC_FP_BITS); ep_curve_get_v1(v1); ep_curve_get_v2(v2); - ep_curve_get_ord(e); - bn_rand_mod(a, e); - BENCH_ADD(bn_rec_glv(b, c, a, e, (const bn_t *)v1, + ep_curve_get_ord(d[1]); + bn_rand_mod(a, d[1]); + BENCH_ADD(bn_rec_glv(b, c, a, d[1], (const bn_t *)v1, (const bn_t *)v2)); } BENCH_END; @@ -920,8 +928,8 @@ static void arith(void) { bn_free(a); bn_free(b); bn_free(c); - bn_free(d); - bn_free(e); + bn_free(d[0]); + bn_free(d[1]); } int main(void) { diff --git a/contrib/relic/bench/bench_cp.c b/contrib/relic/bench/bench_cp.c index 5bf1aafd6..70405f263 100644 --- a/contrib/relic/bench/bench_cp.c +++ b/contrib/relic/bench/bench_cp.c @@ -472,6 +472,7 @@ static void vbnn(void) { } BENCH_END; + bn_free(z); bn_free(h); bn_free(msk); bn_free(ska); @@ -482,10 +483,389 @@ static void vbnn(void) { ec_free(pkb); } +#define MAX_KEYS RLC_MAX(BENCH, 16) +#define MIN_KEYS RLC_MIN(BENCH, 16) + +static void ers(void) { + int size; + ec_t pp, pk[MAX_KEYS + 1]; + bn_t sk[MAX_KEYS + 1], td; + ers_t ring[MAX_KEYS + 1]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + bn_null(td); + ec_null(pp); + + bn_new(td); + ec_new(pp); + for (int i = 0; i <= MAX_KEYS; i++) { + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + ers_null(ring[i]); + ers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + BENCH_RUN("cp_ers_sig") { + BENCH_ADD(cp_ers_sig(td, ring[0], m, 5, sk[0], pk[0], pp)); + } BENCH_END; + + BENCH_RUN("cp_ers_ver") { + BENCH_ADD(cp_ers_ver(td, ring, 1, m, 5, pp)); + } BENCH_END; + + size = 1; + BENCH_FEW("cp_ers_ext", cp_ers_ext(td, ring, &size, m, 5, pk[size], pp), 1); + + size = 1; + cp_ers_sig(td, ring[0], m, 5, sk[0], pk[0], pp); + for (int j = 1; j < MAX_KEYS && size < BENCH; j = j << 1) { + for (int k = 0; k < j && size < BENCH; k++) { + cp_ers_ext(td, ring, &size, m, 5, pk[size], pp); + } + cp_ers_ver(td, ring, size, m, 5, pp); + util_print("(%2d exts) ", j); + BENCH_FEW("cp_ers_ver", cp_ers_ver(td, ring, size, m, 5, pp), 1); + } + + bn_free(td); + ec_free(pp); + for (int i = 0; i <= MAX_KEYS; i++) { + bn_free(sk[i]); + ec_free(pk[i]); + ers_free(ring[i]) + } +} + +static void smlers(void) { + int size; + ec_t pp, pk[MAX_KEYS + 1]; + bn_t sk[MAX_KEYS + 1], td; + smlers_t ring[MAX_KEYS + 1]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + bn_null(td); + ec_null(pp); + + bn_new(td); + ec_new(pp); + for (int i = 0; i <= MAX_KEYS; i++) { + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + smlers_null(ring[i]); + smlers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + BENCH_RUN("cp_smlers_sig") { + BENCH_ADD(cp_smlers_sig(td, ring[0], m, 5, sk[0], pk[0], pp)); + } BENCH_END; + + BENCH_RUN("cp_smlers_ver") { + BENCH_ADD(cp_smlers_ver(td, ring, 1, m, 5, pp)); + } BENCH_END; + + size = 1; + BENCH_FEW("cp_smlers_ext", cp_smlers_ext(td, ring, &size, m, 5, pk[size], pp), 1); + + size = 1; + cp_smlers_sig(td, ring[0], m, 5, sk[0], pk[0], pp); + for (int j = 1; j < MAX_KEYS && size < BENCH; j = j << 1) { + for (int k = 0; k < j && size < BENCH; k++) { + cp_smlers_ext(td, ring, &size, m, 5, pk[size], pp); + } + cp_smlers_ver(td, ring, size, m, 5, pp); + util_print("(%2d exts) ", j); + BENCH_FEW("cp_smlers_ver", cp_smlers_ver(td, ring, size, m, 5, pp), 1); + } + + bn_free(td); + ec_free(pp); + for (int i = 0; i <= MAX_KEYS; i++) { + bn_free(sk[i]); + ec_free(pk[i]); + smlers_free(ring[i]) + } +} + +static void etrs(void) { + int size; + ec_t pp, pk[MAX_KEYS + 1]; + bn_t sk[MAX_KEYS + 1], td[MAX_KEYS + 1], y[MAX_KEYS + 1]; + etrs_t ring[MAX_KEYS + 1]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + ec_null(pp); + ec_new(pp); + for (int i = 0; i <= MAX_KEYS; i++) { + bn_null(td[i]); + bn_new(td[i]); + bn_null(y[i]); + bn_new(y[i]); + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + etrs_null(ring[i]); + etrs_new(ring[i]); + ec_curve_get_ord(sk[i]); + bn_rand_mod(td[i], sk[i]); + bn_rand_mod(y[i], sk[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + BENCH_FEW("cp_etrs_sig", cp_etrs_sig(td, y, MIN_KEYS, ring[0], m, 5, sk[0], pk[0], pp), 1); + + BENCH_FEW("cp_etrs_ver", cp_etrs_ver(1, td, y, MIN_KEYS, ring, 1, m, 5, pp), 1); + + size = 1; + BENCH_FEW("cp_etrs_ext", (size = 1, cp_etrs_ext(td, y, MIN_KEYS, ring, &size, m, 5, pk[size], pp)), 1); + + size = 1; + cp_etrs_sig(td, y, MIN_KEYS, ring[0], m, 5, sk[0], pk[0], pp); + BENCH_FEW("cp_etrs_uni", cp_etrs_uni(1, td, y, MIN_KEYS, ring, &size, m, 5, sk[size], pk[size], pp), 1); + + size = 1; + cp_etrs_sig(td, y, MIN_KEYS, ring[0], m, 5, sk[0], pk[0], pp); + for (int j = 1; j < MIN_KEYS && size < MIN_KEYS; j = j << 1) { + for (int k = 0; k < j && size < MIN_KEYS; k++) { + cp_etrs_ext(td, y, MIN_KEYS, ring, &size, m, 5, pk[size], pp); + } + cp_etrs_ver(1, td+size-1, y+size-1, MIN_KEYS-size+1, ring, size, m, 5, pp); + util_print("(%2d exts) ", j); + BENCH_FEW("cp_etrs_ver", cp_etrs_ver(1, td+size-1, y+size-1, MIN_KEYS-size+1, ring, size, m, 5, pp), 1); + } + + ec_free(pp); + for (int i = 0; i <= MAX_KEYS; i++) { + bn_free(td[i]); + bn_free(y[i]); + bn_free(sk[i]); + ec_free(pk[i]); + etrs_free(ring[i]) + } +} + #endif /* WITH_EC */ #if defined(WITH_PC) +static void pdpub(void) { + bn_t r1, r2; + g1_t p, u1, v1; + g2_t q, u2, v2, w2; + gt_t e, r, g[3]; + + bn_null(r1); + bn_null(r2); + g1_null(p); + g1_null(u1); + g1_null(v1); + g2_null(q); + g2_null(u2); + g2_null(v2); + g2_null(w2); + gt_null(e); + gt_null(r); + gt_null(g[0]); + gt_null(g[1]); + gt_null(g[2]); + + bn_new(r1); + bn_new(r2); + g1_new(p); + g1_new(u1); + g1_new(v1); + g2_new(q); + g2_new(u2); + g2_new(v2); + g2_new(w2); + gt_new(e); + gt_new(r); + gt_new(g[0]); + gt_new(g[1]); + gt_new(g[2]); + + BENCH_RUN("cp_pdpub_gen") { + BENCH_ADD(cp_pdpub_gen(r1, r2, u1, u2, v2, e)); + } BENCH_END; + + BENCH_RUN("cp_pdpub_ask") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_pdpub_ask(v1, w2, p, q, r1, r2, u1, u2, v2)); + } BENCH_END; + + BENCH_RUN("cp_pdpub_ans") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_pdpub_ans(g, p, q, v1, v2, w2)); + } BENCH_END; + + BENCH_RUN("cp_pdpub_ver") { + g1_rand(p); + g2_rand(q); + pc_map(e, p, q); + BENCH_ADD(cp_pdpub_ver(r, g, r1, e)); + } BENCH_END; + + BENCH_RUN("cp_lvpub_gen") { + BENCH_ADD(cp_lvpub_gen(r2, u1, u2, v2, e)); + } BENCH_END; + + BENCH_RUN("cp_lvpub_ask") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_lvpub_ask(r1, v1, w2, p, q, r2, u1, u2, v2)); + } BENCH_END; + + BENCH_RUN("cp_lvpub_ans") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_lvpub_ans(g, p, q, v1, v2, w2)); + } BENCH_END; + + BENCH_RUN("cp_lvpub_ver") { + g1_rand(p); + g2_rand(q); + pc_map(e, p, q); + BENCH_ADD(cp_lvpub_ver(r, g, r1, e)); + } BENCH_END; + + bn_free(r1); + bn_free(r2); + g1_free(p); + g1_free(u1); + g1_free(v1); + g2_free(q); + g2_free(u2); + g2_free(v2); + g2_free(w2); + gt_free(e); + gt_free(r); + gt_free(g[0]); + gt_free(g[1]); + gt_free(g[2]); +} + +static void pdprv(void) { + bn_t r1, r2[3]; + g1_t p, u1[2], v1[3]; + g2_t q, u2[2], v2[4], w2[4]; + gt_t e[2], r, g[4]; + + bn_null(r1); + g1_null(p); + g2_null(q); + gt_null(r); + for (int i = 0; i < 2; i++) { + g1_null(u1[i]); + g2_null(u2[i]); + gt_null(e[i]); + } + for (int i = 0; i < 3; i++) { + g1_null(v1[i]); + bn_null(r2[i]); + } + for (int i = 0; i < 4; i++) { + g2_null(v2[i]); + g2_null(w2[i]); + gt_null(g[i]); + } + + bn_new(r1); + g1_new(p); + g2_new(q); + gt_new(r); + for (int i = 0; i < 2; i++) { + g1_new(u1[i]); + g2_new(u2[i]); + gt_new(e[i]); + } + for (int i = 0; i < 3; i++) { + g1_new(v1[i]); + bn_new(r2[i]); + } + for (int i = 0; i < 4; i++) { + g2_new(v2[i]); + g2_new(w2[i]); + gt_new(g[i]); + } + + BENCH_RUN("cp_pdprv_gen") { + BENCH_ADD(cp_pdprv_gen(r1, r2, u1, u2, v2, e)); + } BENCH_END; + + BENCH_RUN("cp_pdprv_ask") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_pdprv_ask(v1, w2, p, q, r1, r2, u1, u2, v2)); + } BENCH_END; + + BENCH_RUN("cp_pdprv_ans") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_pdprv_ans(g, v1, w2)); + } BENCH_END; + + BENCH_RUN("cp_pdprv_ver") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_pdprv_ver(r, g, r1, e)); + } BENCH_END; + + BENCH_RUN("cp_lvprv_gen") { + BENCH_ADD(cp_lvprv_gen(r1, r2, u1, u2, v2, e)); + } BENCH_END; + + BENCH_RUN("cp_lvprv_ask") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_lvprv_ask(v1, w2, p, q, r1, r2, u1, u2, v2)); + } BENCH_END; + + BENCH_RUN("cp_lvprv_ans") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_lvprv_ans(g, v1, w2)); + } BENCH_END; + + BENCH_RUN("cp_lvprv_ver") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_lvprv_ver(r, g, r1, e)); + } BENCH_END; + + bn_free(r1); + g1_free(p); + g2_free(q); + gt_free(r); + for (int i = 0; i < 2; i++) { + g1_free(u1[i]); + g2_free(u2[i]); + gt_free(e[i]); + } + for (int i = 0; i < 3; i++) { + g1_free(v1[i]); + bn_free(r2[i]); + } + for (int i = 0; i < 4; i++) { + g2_free(v2[i]); + g2_free(w2[i]); + gt_free(g[i]); + } +} + static void sokaka(void) { sokaka_t k; bn_t s; @@ -1425,6 +1805,76 @@ static void lhs(void) { } } +#define M 5 /* Number of server messages (larger). */ +#define N 2 /* Number of client messages. */ + +static void psi(void) { + bn_t q, r, x[M], y[N], z[M]; + g1_t d, s[M + 1]; + g2_t u[M], ss; + gt_t t[M]; + int len; + + bn_new(q); + bn_new(r); + g1_new(d); + g2_new(ss); + for (int i = 0; i < M; i++) { + bn_null(x[i]); + bn_null(z[i]); + g1_null(s[i]); + bn_new(x[i]); + bn_new(z[i]); + g1_new(s[i]); + } + for (int i = 0; i < N; i++) { + bn_null(y[i]); + g2_null(u[i]); + gt_null(t[i]); + bn_new(y[i]); + g2_new(u[i]); + } + + pc_get_ord(q); + for (int j = 0; j < M; j++) { + bn_rand_mod(x[j], q); + } + for (int j = 0; j < N; j++) { + bn_rand_mod(y[j], q); + } + + BENCH_RUN("cp_lapsi_gen (5)") { + BENCH_ADD(cp_lapsi_gen(q, ss, s, M)); + } BENCH_END; + + BENCH_RUN("cp_lapsi_ask (5)") { + BENCH_ADD(cp_lapsi_ask(d, r, x, s, M)); + } BENCH_END; + + BENCH_RUN("cp_lapsi_ans (2)") { + BENCH_ADD(cp_lapsi_ans(t, u, d, ss, y, N)); + } BENCH_END; + + BENCH_RUN("cp_lapsi_int") { + BENCH_ADD(cp_lapsi_int(z, &len, q, d, x, M, t, u, N)); + } BENCH_END; + + bn_free(q); + bn_free(r); + g1_free(d); + g2_free(ss); + for (int i = 0; i < M; i++) { + bn_free(x[i]); + bn_free(z[i]); + g1_free(s[i]); + } + for (int i = 0; i < N; i++) { + bn_free(y[i]); + g2_free(u[i]); + gt_free(t[i]); + } +} + #endif /* WITH_PC */ int main(void) { @@ -1446,22 +1896,25 @@ int main(void) { #endif #if defined(WITH_EC) - util_banner("Protocols based on elliptic curves:\n", 0); if (ec_param_set_any() == RLC_OK) { + util_banner("Protocols based on elliptic curves:\n", 0); ecdh(); ecmqv(); ecies(); ecdsa(); ecss(); vbnn(); - } else { - RLC_THROW(ERR_NO_CURVE); + ers(); + smlers(); + etrs(); } #endif #if defined(WITH_PC) - util_banner("Protocols based on pairings:\n", 0); if (pc_param_set_any() == RLC_OK) { + util_banner("Protocols based on pairings:\n", 0); + pdpub(); + pdprv(); sokaka(); ibe(); bgn(); @@ -1474,8 +1927,7 @@ int main(void) { #endif zss(); lhs(); - } else { - RLC_THROW(ERR_NO_CURVE); + psi(); } #endif diff --git a/contrib/relic/bench/bench_ed.c b/contrib/relic/bench/bench_ed.c index 7dfa39424..5dc267dc1 100644 --- a/contrib/relic/bench/bench_ed.c +++ b/contrib/relic/bench/bench_ed.c @@ -326,7 +326,7 @@ static void arith(void) { BENCH_ADD(ed_sub_extnd(r, p, q)); } BENCH_END; - BENCH_RUN("ed_sub_projc (z2 = 1)") { + BENCH_RUN("ed_sub_extnd (z2 = 1)") { ed_rand(p); ed_rand(q); ed_add_extnd(p, p, q); @@ -335,12 +335,12 @@ static void arith(void) { BENCH_ADD(ed_sub_extnd(r, p, q)); } BENCH_END; - BENCH_RUN("ed_sub_projc (z1,z2 = 1)") { + BENCH_RUN("ed_sub_extnd (z1,z2 = 1)") { ed_rand(p); ed_norm(p, p); ed_rand(q); ed_norm(q, q); - BENCH_ADD(ed_sub_projc(r, p, q)); + BENCH_ADD(ed_sub_extnd(r, p, q)); } BENCH_END; #endif @@ -373,7 +373,7 @@ static void arith(void) { } BENCH_END; #endif -#if ED_ADD == PROJC || !defined(STRIP) +#if ED_ADD == EXTND || !defined(STRIP) BENCH_RUN("ed_dbl_extnd") { ed_rand(p); ed_rand(q); diff --git a/contrib/relic/bench/bench_ep.c b/contrib/relic/bench/bench_ep.c index bd95bb56c..04ccdfc83 100644 --- a/contrib/relic/bench/bench_ep.c +++ b/contrib/relic/bench/bench_ep.c @@ -188,7 +188,7 @@ static void util(void) { static void arith(void) { ep_t p, q, r, t[RLC_EP_TABLE_MAX]; - bn_t k, l, n; + bn_t k, l[2], n; ep_null(p); ep_null(q); @@ -202,7 +202,8 @@ static void arith(void) { ep_new(r); bn_new(k); bn_new(n); - bn_new(l); + bn_new(l[0]); + bn_new(l[1]); ep_curve_get_ord(n); @@ -498,60 +499,76 @@ static void arith(void) { } #endif BENCH_RUN("ep_mul_sim") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep_rand(p); ep_rand(q); - BENCH_ADD(ep_mul_sim(r, p, k, q, l)); + BENCH_ADD(ep_mul_sim(r, p, l[0], q, l[1])); } BENCH_END; #if EP_SIM == BASIC || !defined(STRIP) BENCH_RUN("ep_mul_sim_basic") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep_rand(p); ep_rand(q); - BENCH_ADD(ep_mul_sim_basic(r, p, k, q, l)); + BENCH_ADD(ep_mul_sim_basic(r, p, l[0], q, l[1])); } BENCH_END; #endif #if EP_SIM == TRICK || !defined(STRIP) BENCH_RUN("ep_mul_sim_trick") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep_rand(p); ep_rand(q); - BENCH_ADD(ep_mul_sim_trick(r, p, k, q, l)); + BENCH_ADD(ep_mul_sim_trick(r, p, l[0], q, l[1])); } BENCH_END; #endif #if EP_SIM == INTER || !defined(STRIP) BENCH_RUN("ep_mul_sim_inter") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep_rand(p); ep_rand(q); - BENCH_ADD(ep_mul_sim_inter(r, p, k, q, l)); + BENCH_ADD(ep_mul_sim_inter(r, p, l[0], q, l[1])); } BENCH_END; #endif #if EP_SIM == JOINT || !defined(STRIP) BENCH_RUN("ep_mul_sim_joint") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep_rand(p); ep_rand(q); - BENCH_ADD(ep_mul_sim_joint(r, p, k, q, l)); + BENCH_ADD(ep_mul_sim_joint(r, p, l[0], q, l[1])); } BENCH_END; #endif BENCH_RUN("ep_mul_sim_gen") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep_rand(q); - BENCH_ADD(ep_mul_sim_gen(r, k, q, l)); + BENCH_ADD(ep_mul_sim_gen(r, l[0], q, l[1])); + } BENCH_END; + + for (int i = 0; i < 2; i++) { + ep_new(t[i]); + } + + BENCH_RUN("ep_mul_sim_lot (2)") { + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); + ep_rand(t[0]); + ep_rand(t[1]); + BENCH_ADD(ep_mul_sim_lot(r, t, l, 2)); } BENCH_END; + for (int i = 0; i < 2; i++) { + ep_free(t[i]); + } + BENCH_RUN("ep_map") { uint8_t msg[5]; rand_bytes(msg, 5); @@ -572,7 +589,8 @@ static void arith(void) { ep_free(q); ep_free(r); bn_free(k); - bn_free(l); + bn_free(l[0]); + bn_free(l[1]); bn_free(n); } diff --git a/contrib/relic/bench/bench_epx.c b/contrib/relic/bench/bench_epx.c index eee40decb..487d3dad6 100644 --- a/contrib/relic/bench/bench_epx.c +++ b/contrib/relic/bench/bench_epx.c @@ -34,25 +34,25 @@ #include "relic.h" #include "relic_bench.h" -static void memory(void) { - ep2_t a[BENCH]; +static void memory2(void) { + ep4_t a[BENCH]; - BENCH_FEW("ep2_null", ep2_null(a[i]), 1); + BENCH_FEW("ep4_null", ep4_null(a[i]), 1); - BENCH_FEW("ep2_new", ep2_new(a[i]), 1); + BENCH_FEW("ep4_new", ep4_new(a[i]), 1); for (int i = 0; i < BENCH; i++) { - ep2_free(a[i]); + ep4_free(a[i]); } for (int i = 0; i < BENCH; i++) { - ep2_new(a[i]); + ep4_new(a[i]); } - BENCH_FEW("ep2_free", ep2_free(a[i]), 1); + BENCH_FEW("ep4_free", ep4_free(a[i]), 1); (void)a; } -static void util(void) { +static void util2(void) { ep2_t p, q, t[2]; uint8_t bin[4 * RLC_FP_BYTES + 1]; int l; @@ -178,9 +178,9 @@ static void util(void) { ep2_free(t[1]); } -static void arith(void) { +static void arith2(void) { ep2_t p, q, r, t[RLC_EPX_TABLE_MAX]; - bn_t k, n, l; + bn_t k, n, l[2]; fp2_t s; ep2_null(p); @@ -198,7 +198,8 @@ static void arith(void) { ep2_new(r); bn_new(k); bn_new(n); - bn_new(l); + bn_new(l[0]); + bn_new(l[1]); fp2_new(s); ep2_curve_get_ord(n); @@ -467,60 +468,76 @@ static void arith(void) { #endif BENCH_RUN("ep2_mul_sim") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep2_rand(p); ep2_rand(q); - BENCH_ADD(ep2_mul_sim(r, p, k, q, l)); + BENCH_ADD(ep2_mul_sim(r, p, l[0], q, l[1])); } BENCH_END; #if EP_SIM == BASIC || !defined(STRIP) BENCH_RUN("ep2_mul_sim_basic") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep2_rand(p); ep2_rand(q); - BENCH_ADD(ep2_mul_sim_basic(r, p, k, q, l)); + BENCH_ADD(ep2_mul_sim_basic(r, p, l[0], q, l[1])); } BENCH_END; #endif #if EP_SIM == TRICK || !defined(STRIP) BENCH_RUN("ep2_mul_sim_trick") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep2_rand(p); ep2_rand(q); - BENCH_ADD(ep2_mul_sim_trick(r, p, k, q, l)); + BENCH_ADD(ep2_mul_sim_trick(r, p, l[0], q, l[1])); } BENCH_END; #endif #if EP_SIM == INTER || !defined(STRIP) BENCH_RUN("ep2_mul_sim_inter") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep2_rand(p); ep2_rand(q); - BENCH_ADD(ep2_mul_sim_inter(r, p, k, q, l)); + BENCH_ADD(ep2_mul_sim_inter(r, p, l[0], q, l[1])); } BENCH_END; #endif #if EP_SIM == JOINT || !defined(STRIP) BENCH_RUN("ep2_mul_sim_joint") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep2_rand(p); ep2_rand(q); - BENCH_ADD(ep2_mul_sim_joint(r, p, k, q, l)); + BENCH_ADD(ep2_mul_sim_joint(r, p, l[0], q, l[1])); } BENCH_END; #endif BENCH_RUN("ep2_mul_sim_gen") { - bn_rand_mod(k, n); - bn_rand_mod(l, n); + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); ep2_rand(q); - BENCH_ADD(ep2_mul_sim_gen(r, k, q, l)); + BENCH_ADD(ep2_mul_sim_gen(r, l[0], q, l[1])); + } BENCH_END; + + for (int i = 0; i < 2; i++) { + ep2_new(t[i]); + } + + BENCH_RUN("ep2_mul_sim_lot (2)") { + bn_rand_mod(l[0], n); + bn_rand_mod(l[1], n); + ep2_rand(t[0]); + ep2_rand(t[1]); + BENCH_ADD(ep2_mul_sim_lot(r, t, l, 2)); } BENCH_END; + for (int i = 0; i < 2; i++) { + ep2_free(t[i]); + } + BENCH_RUN("ep2_frb") { ep2_rand(q); BENCH_ADD(ep2_frb(r, q, 1)); @@ -547,11 +564,502 @@ static void arith(void) { ep2_free(r); bn_free(k); bn_free(n); - bn_free(l); + bn_free(l[0]); + bn_free(l[1]); fp2_free(s); } +static void memory4(void) { + ep4_t a[BENCH]; + + BENCH_FEW("ep4_null", ep4_null(a[i]), 1); + + BENCH_FEW("ep4_new", ep4_new(a[i]), 1); + for (int i = 0; i < BENCH; i++) { + ep4_free(a[i]); + } + + for (int i = 0; i < BENCH; i++) { + ep4_new(a[i]); + } + BENCH_FEW("ep4_free", ep4_free(a[i]), 1); + + (void)a; +} + +static void util4(void) { + ep4_t p, q, t[2]; + uint8_t bin[8 * RLC_FP_BYTES + 1]; + int l; + + ep4_null(p); + ep4_null(q); + ep4_null(t[0]); + ep4_null(t[1]); + + ep4_new(p); + ep4_new(q); + ep4_new(t[0]); + ep4_new(t[1]); + + BENCH_RUN("ep4_is_infty") { + ep4_rand(p); + BENCH_ADD(ep4_is_infty(p)); + } + BENCH_END; + + BENCH_RUN("ep4_set_infty") { + ep4_rand(p); + BENCH_ADD(ep4_set_infty(p)); + } + BENCH_END; + + BENCH_RUN("ep4_copy") { + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_copy(p, q)); + } + BENCH_END; + + BENCH_RUN("ep4_cmp") { + ep4_rand(p); + ep4_dbl(p, p); + ep4_rand(q); + ep4_dbl(q, q); + BENCH_ADD(ep4_cmp(p, q)); + } BENCH_END; + + BENCH_RUN("ep4_norm") { + ep4_rand(p); + ep4_dbl(p, p); + BENCH_ADD(ep4_norm(p, p)); + } BENCH_END; + + BENCH_RUN("ep4_norm_sim (2)") { + ep4_rand(t[0]); + ep4_rand(t[1]); + ep4_dbl(t[0], t[0]); + ep4_dbl(t[1], t[1]); + BENCH_ADD(ep4_norm_sim(t, t, 2)); + } BENCH_END; + + BENCH_RUN("ep4_cmp (1 norm)") { + ep4_rand(p); + ep4_dbl(p, p); + ep4_rand(q); + BENCH_ADD(ep4_cmp(p, q)); + } BENCH_END; + + BENCH_RUN("ep4_cmp (2 norm)") { + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_cmp(p, q)); + } BENCH_END; + + BENCH_RUN("ep4_rand") { + BENCH_ADD(ep4_rand(p)); + } + BENCH_END; + + BENCH_RUN("ep4_blind") { + BENCH_ADD(ep4_blind(p, p)); + } + BENCH_END; + + BENCH_RUN("ep4_on_curve") { + ep4_rand(p); + BENCH_ADD(ep4_on_curve(p)); + } BENCH_END; + + BENCH_RUN("ep4_size_bin") { + ep4_rand(p); + BENCH_ADD(ep4_size_bin(p, 0)); + } BENCH_END; + + BENCH_RUN("ep4_write_bin") { + ep4_rand(p); + l = ep4_size_bin(p, 0); + BENCH_ADD(ep4_write_bin(bin, l, p, 0)); + } BENCH_END; + + BENCH_RUN("ep4_read_bin") { + ep4_rand(p); + l = ep4_size_bin(p, 0); + ep4_write_bin(bin, l, p, 0); + BENCH_ADD(ep4_read_bin(p, bin, l)); + } BENCH_END; + + ep4_free(p); + ep4_free(q); + ep4_free(t[0]); + ep4_free(t[1]); +} + +static void arith4(void) { + ep4_t p, q, r, t[RLC_EPX_TABLE_MAX]; + bn_t k, n, l; + fp4_t s; + + ep4_null(p); + ep4_null(q); + ep4_null(r); + bn_null(k); + bn_null(n); + fp4_null(s); + for (int i = 0; i < RLC_EPX_TABLE_MAX; i++) { + ep4_null(t[i]); + } + + ep4_new(p); + ep4_new(q); + ep4_new(r); + bn_new(k); + bn_new(n); + bn_new(l); + fp4_new(s); + + ep4_curve_get_ord(n); + + BENCH_RUN("ep4_add") { + ep4_rand(p); + ep4_rand(q); + ep4_add(p, p, q); + ep4_rand(q); + ep4_rand(p); + ep4_add(q, q, p); + BENCH_ADD(ep4_add(r, p, q)); + } + BENCH_END; + +#if EP_ADD == BASIC || !defined(STRIP) + BENCH_RUN("ep4_add_basic") { + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_add_basic(r, p, q)); + } + BENCH_END; + + BENCH_RUN("ep4_add_slp_basic") { + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_add_slp_basic(r, s, p, q)); + } + BENCH_END; +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + BENCH_RUN("ep4_add_projc") { + ep4_rand(p); + ep4_rand(q); + ep4_add_projc(p, p, q); + ep4_rand(q); + ep4_rand(p); + ep4_add_projc(q, q, p); + BENCH_ADD(ep4_add_projc(r, p, q)); + } + BENCH_END; + + BENCH_RUN("ep4_add_projc (z2 = 1)") { + ep4_rand(p); + ep4_rand(q); + ep4_add_projc(p, p, q); + ep4_rand(q); + ep4_norm(q, q); + BENCH_ADD(ep4_add_projc(r, p, q)); + } + BENCH_END; + + BENCH_RUN("ep4_add_projc (z1,z2 = 1)") { + ep4_rand(p); + ep4_norm(p, p); + ep4_rand(q); + ep4_norm(q, q); + BENCH_ADD(ep4_add_projc(r, p, q)); + } + BENCH_END; +#endif + + BENCH_RUN("ep4_sub") { + ep4_rand(p); + ep4_rand(q); + ep4_add(p, p, q); + ep4_rand(q); + ep4_rand(p); + ep4_add(q, q, p); + BENCH_ADD(ep4_sub(r, p, q)); + } + BENCH_END; + + BENCH_RUN("ep4_dbl") { + ep4_rand(p); + ep4_rand(q); + ep4_add(p, p, q); + BENCH_ADD(ep4_dbl(r, p)); + } + BENCH_END; + +#if EP_ADD == BASIC || !defined(STRIP) + BENCH_RUN("ep4_dbl_basic") { + ep4_rand(p); + BENCH_ADD(ep4_dbl_basic(r, p)); + } + BENCH_END; + + BENCH_RUN("ep4_dbl_slp_basic") { + ep4_rand(p); + BENCH_ADD(ep4_dbl_slp_basic(r, s, p)); + } + BENCH_END; +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + BENCH_RUN("ep4_dbl_projc") { + ep4_rand(p); + ep4_rand(q); + ep4_add_projc(p, p, q); + BENCH_ADD(ep4_dbl_projc(r, p)); + } + BENCH_END; + + BENCH_RUN("ep4_dbl_projc (z1 = 1)") { + ep4_rand(p); + ep4_norm(p, p); + BENCH_ADD(ep4_dbl_projc(r, p)); + } + BENCH_END; +#endif + + BENCH_RUN("ep4_neg") { + ep4_rand(p); + ep4_rand(q); + ep4_add(p, p, q); + BENCH_ADD(ep4_neg(r, p)); + } + BENCH_END; + + BENCH_RUN("ep4_mul") { + bn_rand_mod(k, n); + BENCH_ADD(ep4_mul(q, p, k)); + } BENCH_END; + +#if EP_MUL == BASIC || !defined(STRIP) + BENCH_RUN("ep4_mul_basic") { + bn_rand_mod(k, n); + BENCH_ADD(ep4_mul_basic(q, p, k)); + } BENCH_END; +#endif + +#if EP_MUL == SLIDE || !defined(STRIP) + BENCH_RUN("ep4_mul_slide") { + bn_rand_mod(k, n); + ep4_rand(p); + BENCH_ADD(ep4_mul_slide(q, p, k)); + } BENCH_END; +#endif + +#if EP_MUL == MONTY || !defined(STRIP) + BENCH_RUN("ep4_mul_monty") { + bn_rand_mod(k, n); + ep4_rand(p); + BENCH_ADD(ep4_mul_monty(q, p, k)); + } BENCH_END; +#endif + +#if EP_MUL == LWNAF || !defined(STRIP) + BENCH_RUN("ep4_mul_lwnaf") { + bn_rand_mod(k, n); + ep4_rand(p); + BENCH_ADD(ep4_mul_lwnaf(q, p, k)); + } BENCH_END; +#endif + + BENCH_RUN("ep4_mul_gen") { + bn_rand_mod(k, n); + BENCH_ADD(ep4_mul_gen(q, k)); + } BENCH_END; + + BENCH_RUN("ep4_mul_dig") { + bn_rand(k, RLC_POS, RLC_DIG); + bn_rand_mod(k, n); + BENCH_ADD(ep4_mul_dig(p, q, k->dp[0])); + } + BENCH_END; + + for (int i = 0; i < RLC_EPX_TABLE_MAX; i++) { + ep4_new(t[i]); + } + + BENCH_RUN("ep4_mul_pre") { + ep4_rand(p); + BENCH_ADD(ep4_mul_pre(t, p)); + } BENCH_END; + + BENCH_RUN("ep4_mul_fix") { + bn_rand_mod(k, n); + ep4_rand(p); + ep4_mul_pre(t, p); + BENCH_ADD(ep4_mul_fix(q, t, k)); + } BENCH_END; + + for (int i = 0; i < RLC_EPX_TABLE_MAX; i++) { + ep4_free(t[i]); + } + +#if EP_FIX == BASIC || !defined(STRIP) + for (int i = 0; i < RLC_EPX_TABLE_BASIC; i++) { + ep4_new(t[i]); + } + BENCH_RUN("ep4_mul_pre_basic") { + ep4_rand(p); + BENCH_ADD(ep4_mul_pre_basic(t, p)); + } BENCH_END; + + BENCH_RUN("ep4_mul_fix_basic") { + bn_rand_mod(k, n); + ep4_rand(p); + ep4_mul_pre_basic(t, p); + BENCH_ADD(ep4_mul_fix_basic(q, t, k)); + } BENCH_END; + for (int i = 0; i < RLC_EPX_TABLE_BASIC; i++) { + ep4_free(t[i]); + } +#endif + +#if EP_FIX == COMBS || !defined(STRIP) + for (int i = 0; i < RLC_EPX_TABLE_COMBS; i++) { + ep4_new(t[i]); + } + BENCH_RUN("ep4_mul_pre_combs") { + ep4_rand(p); + BENCH_ADD(ep4_mul_pre_combs(t, p)); + } BENCH_END; + + BENCH_RUN("ep4_mul_fix_combs") { + bn_rand_mod(k, n); + ep4_rand(p); + ep4_mul_pre_combs(t, p); + BENCH_ADD(ep4_mul_fix_combs(q, t, k)); + } BENCH_END; + for (int i = 0; i < RLC_EPX_TABLE_COMBS; i++) { + ep4_free(t[i]); + } +#endif + +#if EP_FIX == COMBD || !defined(STRIP) + for (int i = 0; i < RLC_EPX_TABLE_COMBD; i++) { + ep4_new(t[i]); + } + BENCH_RUN("ep4_mul_pre_combd") { + BENCH_ADD(ep4_mul_pre_combd(t, p)); + } BENCH_END; + + BENCH_RUN("ep4_mul_fix_combd") { + bn_rand_mod(k, n); + ep4_mul_pre_combd(t, p); + BENCH_ADD(ep4_mul_fix_combd(q, t, k)); + } BENCH_END; + for (int i = 0; i < RLC_EPX_TABLE_COMBD; i++) { + ep4_free(t[i]); + } +#endif + +#if EP_FIX == LWNAF || !defined(STRIP) + for (int i = 0; i < RLC_EPX_TABLE_LWNAF; i++) { + ep4_new(t[i]); + } + BENCH_RUN("ep4_mul_pre_lwnaf") { + ep4_rand(p); + BENCH_ADD(ep4_mul_pre_lwnaf(t, p)); + } BENCH_END; + + BENCH_RUN("ep4_mul_fix_lwnaf") { + bn_rand_mod(k, n); + ep4_rand(p); + ep4_mul_pre_lwnaf(t, p); + BENCH_ADD(ep4_mul_fix_lwnaf(q, t, k)); + } BENCH_END; + for (int i = 0; i < RLC_EPX_TABLE_LWNAF; i++) { + ep4_free(t[i]); + } +#endif + + BENCH_RUN("ep4_mul_sim") { + bn_rand_mod(k, n); + bn_rand_mod(l, n); + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_mul_sim(r, p, k, q, l)); + } BENCH_END; + +#if EP_SIM == BASIC || !defined(STRIP) + BENCH_RUN("ep4_mul_sim_basic") { + bn_rand_mod(k, n); + bn_rand_mod(l, n); + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_mul_sim_basic(r, p, k, q, l)); + } BENCH_END; +#endif + +#if EP_SIM == TRICK || !defined(STRIP) + BENCH_RUN("ep4_mul_sim_trick") { + bn_rand_mod(k, n); + bn_rand_mod(l, n); + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_mul_sim_trick(r, p, k, q, l)); + } BENCH_END; +#endif + +#if EP_SIM == INTER || !defined(STRIP) + BENCH_RUN("ep4_mul_sim_inter") { + bn_rand_mod(k, n); + bn_rand_mod(l, n); + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_mul_sim_inter(r, p, k, q, l)); + } BENCH_END; +#endif + +#if EP_SIM == JOINT || !defined(STRIP) + BENCH_RUN("ep4_mul_sim_joint") { + bn_rand_mod(k, n); + bn_rand_mod(l, n); + ep4_rand(p); + ep4_rand(q); + BENCH_ADD(ep4_mul_sim_joint(r, p, k, q, l)); + } BENCH_END; +#endif + + BENCH_RUN("ep4_mul_sim_gen") { + bn_rand_mod(k, n); + bn_rand_mod(l, n); + ep4_rand(q); + BENCH_ADD(ep4_mul_sim_gen(r, k, q, l)); + } BENCH_END; + + BENCH_RUN("ep4_frb") { + ep4_rand(q); + BENCH_ADD(ep4_frb(r, q, 1)); + } BENCH_END; + + BENCH_RUN("ep4_map") { + uint8_t msg[5]; + rand_bytes(msg, 5); + BENCH_ADD(ep4_map(p, msg, 5)); + } BENCH_END; + + ep4_free(p); + ep4_free(q); + ep4_free(r); + bn_free(k); + bn_free(n); + bn_free(l); + fp4_free(s); +} + int main(void) { + int r0, r1; if (core_init() != RLC_OK) { core_clean(); return 1; @@ -567,20 +1075,33 @@ int main(void) { return 0; } - if (ep2_curve_is_twist() == 0) { - RLC_THROW(ERR_NO_CURVE); - core_clean(); - return 0; + if ((r0 = ep2_curve_is_twist())) { + ep_param_print(); + + util_banner("Utilities:", 1); + memory2(); + util2(); + + util_banner("Arithmetic:", 1); + arith2(); } - ep_param_print(); + if ((r1 = ep4_curve_is_twist())) { + ep_param_print(); - util_banner("Utilities:", 1); - memory(); - util(); + util_banner("Utilities:", 1); + memory4(); + util4(); + + util_banner("Arithmetic:", 1); + arith4(); + } - util_banner("Arithmetic:", 1); - arith(); + if (!r0 && !r1) { + RLC_THROW(ERR_NO_CURVE); + core_clean(); + return 0; + } core_clean(); return 0; diff --git a/contrib/relic/bench/bench_fb.c b/contrib/relic/bench/bench_fb.c index 477850293..41fbb026e 100644 --- a/contrib/relic/bench/bench_fb.c +++ b/contrib/relic/bench/bench_fb.c @@ -161,7 +161,8 @@ static void util(void) { } static void arith(void) { - fb_t a, b, c, d[2], t[RLC_FB_TABLE_MAX]; + fb_t a, b, c, d[2]; + fb_st t[RLC_FB_TABLE_MAX]; dv_t e; bn_t f; int bits; @@ -171,9 +172,6 @@ static void arith(void) { fb_null(c); fb_null(d[0]); fb_null(d[1]); - for (int i = 0; i < RLC_FB_TABLE_MAX; i++) { - fb_null(t[i]); - } dv_null(e); bn_null(f); @@ -513,22 +511,14 @@ static void arith(void) { BENCH_END; #endif - for (int i = 0; i < RLC_FB_TABLE; i++) { - fb_new(t[i]); - } - BENCH_RUN("fb_itr") { fb_rand(a); bn_rand(f, RLC_POS, 8); fb_itr_pre(t, f->dp[0]); - BENCH_ADD(fb_itr(c, a, f->dp[0], (const fb_t *)t)); + BENCH_ADD(fb_itr(c, a, f->dp[0], t)); } BENCH_END; - for (int i = 0; i < RLC_FB_TABLE; i++) { - fb_free(t[i]); - } - #if FB_ITR == BASIC || !defined(STRIP) BENCH_RUN("fb_itr_basic") { fb_rand(a); @@ -539,19 +529,13 @@ static void arith(void) { #endif #if FB_ITR == QUICK || !defined(STRIP) - for (int i = 0; i < RLC_FB_TABLE_QUICK; i++) { - fb_new(t[i]); - } BENCH_RUN("fb_itr_quick") { fb_rand(a); bn_rand(f, RLC_POS, 8); fb_itr_pre_quick(t, f->dp[0]); - BENCH_ADD(fb_itr_quick(c, a, (const fb_t *)t)); + BENCH_ADD(fb_itr_quick(c, a, t)); } BENCH_END; - for (int i = 0; i < RLC_FB_TABLE_QUICK; i++) { - fb_new(t[i]); - } #endif fb_free(a); diff --git a/contrib/relic/bench/bench_fp.c b/contrib/relic/bench/bench_fp.c index c2887f650..39204de2f 100644 --- a/contrib/relic/bench/bench_fp.c +++ b/contrib/relic/bench/bench_fp.c @@ -526,6 +526,14 @@ static void arith(void) { BENCH_END; #endif +#if FP_INV == JMPDS || !defined(STRIP) + BENCH_RUN("fp_inv_jmpds") { + fp_rand(a); + BENCH_ADD(fp_inv_jmpds(c, a)); + } + BENCH_END; +#endif + #if FP_INV == LOWER || !defined(STRIP) BENCH_RUN("fp_inv_lower") { fp_rand(a); @@ -541,6 +549,49 @@ static void arith(void) { } BENCH_END; + BENCH_RUN("fp_smb") { + fp_rand(a); + fp_sqr(a, a); + BENCH_ADD(fp_smb(a)); + } + BENCH_END; + +#if FP_SMB == BASIC || !defined(STRIP) + BENCH_RUN("fp_smb_basic") { + fp_rand(a); + fp_sqr(a, a); + BENCH_ADD(fp_smb_basic(a)); + } + BENCH_END; +#endif + +#if FP_SMB == DIVST || !defined(STRIP) + BENCH_RUN("fp_smb_divst") { + fp_rand(a); + fp_sqr(a, a); + BENCH_ADD(fp_smb_divst(a)); + } + BENCH_END; +#endif + +#if FP_SMB == JMPDS || !defined(STRIP) + BENCH_RUN("fp_smb_jmpds") { + fp_rand(a); + fp_sqr(a, a); + BENCH_ADD(fp_smb_jmpds(a)); + } + BENCH_END; +#endif + +#if FP_SMB == LOWER || !defined(STRIP) + BENCH_RUN("fp_smb_lower") { + fp_rand(a); + fp_sqr(a, a); + BENCH_ADD(fp_smb_lower(a)); + } + BENCH_END; +#endif + BENCH_RUN("fp_exp") { fp_rand(a); bn_rand(e, RLC_POS, RLC_FP_BITS); diff --git a/contrib/relic/bench/bench_fpx.c b/contrib/relic/bench/bench_fpx.c index 0546808a0..62ee13cc3 100644 --- a/contrib/relic/bench/bench_fpx.c +++ b/contrib/relic/bench/bench_fpx.c @@ -909,9 +909,17 @@ static void arith4(void) { } BENCH_END; + BENCH_RUN("fp4_srt") { + fp4_rand(a); + fp4_sqr(a, a); + BENCH_ADD(fp4_srt(c, a)); + } + BENCH_END; + fp4_free(a); fp4_free(b); fp4_free(c); + bn_free(d); } static void memory6(void) { @@ -2256,25 +2264,47 @@ static void util24(void) { } BENCH_END; - BENCH_RUN("fp24_size_bin") { + BENCH_RUN("fp24_size_bin (0)") { + fp24_rand(a); + BENCH_ADD(fp24_size_bin(a, 0)); + } + BENCH_END; + + BENCH_RUN("fp24_size_bin (1)") { + fp24_rand(a); + fp24_conv_cyc(a, a); + BENCH_ADD(fp24_size_bin(a, 1)); + } + BENCH_END; + + BENCH_RUN("fp24_write_bin (0)") { fp24_rand(a); - BENCH_ADD(fp24_size_bin(a)); + BENCH_ADD(fp24_write_bin(bin, sizeof(bin), a, 0)); } BENCH_END; - BENCH_RUN("fp24_write_bin") { + BENCH_RUN("fp24_write_bin (1)") { fp24_rand(a); - BENCH_ADD(fp24_write_bin(bin, sizeof(bin), a)); + fp24_conv_cyc(a, a); + BENCH_ADD(fp24_write_bin(bin, 32 * RLC_FP_BYTES, a, 1)); } BENCH_END; - BENCH_RUN("fp24_read_bin") { + BENCH_RUN("fp24_read_bin (0)") { fp24_rand(a); - fp24_write_bin(bin, sizeof(bin), a); + fp24_write_bin(bin, sizeof(bin), a, 0); BENCH_ADD(fp24_read_bin(a, bin, sizeof(bin))); } BENCH_END; + BENCH_RUN("fp24_read_bin (1)") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_write_bin(bin, fp24_size_bin(a, 1), a, 1); + BENCH_ADD(fp24_read_bin(a, bin, 32 * RLC_FP_BYTES)); + } + BENCH_END; + BENCH_RUN("fp24_cmp") { fp24_rand(a); fp24_rand(b); @@ -2293,12 +2323,14 @@ static void util24(void) { } static void arith24(void) { - fp24_t a, b, c; + fp24_t a, b, c, d[2]; bn_t e; fp24_new(a); fp24_new(b); fp24_new(c); + fp24_new(d[0]); + fp24_new(d[1]); bn_new(e); BENCH_RUN("fp24_add") { @@ -2362,6 +2394,38 @@ static void arith24(void) { BENCH_END; #endif + BENCH_RUN("fp24_test_cyc") { + fp24_rand(a); + fp24_conv_cyc(a, a); + BENCH_ADD(fp24_test_cyc(a)); + } + BENCH_END; + + BENCH_RUN("fp24_conv_cyc") { + fp24_rand(a); + BENCH_ADD(fp24_conv_cyc(c, a)); + } + BENCH_END; + + BENCH_RUN("fp24_back_cyc") { + fp24_rand(a); + BENCH_ADD(fp24_back_cyc(c, a)); + } + BENCH_END; + + BENCH_RUN("fp24_back_cyc (2)") { + fp24_rand(d[0]); + fp24_rand(d[1]); + BENCH_ADD(fp24_back_cyc_sim(d, d, 2)); + } + BENCH_END; + + BENCH_RUN("fp24_conv_cyc") { + fp24_rand(a); + BENCH_ADD(fp24_conv_cyc(c, a)); + } + BENCH_END; + BENCH_RUN("fp24_inv") { fp24_rand(a); BENCH_ADD(fp24_inv(c, a)); @@ -2375,15 +2439,70 @@ static void arith24(void) { } BENCH_END; + BENCH_RUN("fp24_exp (cyc)") { + fp24_rand(a); + fp24_conv_cyc(a, a); + bn_rand(e, RLC_POS, RLC_FP_BITS); + BENCH_ADD(fp24_exp(c, a, e)); + } + BENCH_END; + + BENCH_RUN("fp24_exp_cyc (param or sparse)") { + fp24_rand(a); + fp24_conv_cyc(a, a); + bn_zero(e); + fp_prime_get_par(e); + if (bn_is_zero(e)) { + bn_set_2b(e, RLC_FP_BITS - 1); + bn_set_bit(e, RLC_FP_BITS / 2, 1); + bn_set_bit(e, 0, 1); + } + BENCH_ADD(fp24_exp_cyc(c, a, e)); + } + BENCH_END; + + BENCH_RUN("fp24_exp_cyc_sps (param)") { + const int *k; + int l; + k = fp_prime_get_par_sps(&l); + fp24_rand(a); + BENCH_ADD(fp24_exp_cyc_sps(c, a, k, l, RLC_POS)); + } + BENCH_END; + + BENCH_RUN("fp24_exp_dig") { + fp24_rand(a); + bn_rand(e, RLC_POS, RLC_DIG); + BENCH_ADD(fp24_exp_dig(c, a, e->dp[0])); + } + BENCH_END; + BENCH_RUN("fp24_frb") { fp24_rand(a); BENCH_ADD(fp24_frb(c, a, 1)); } BENCH_END; + BENCH_RUN("fp24_pck") { + fp24_rand(a); + fp24_conv_cyc(a, a); + BENCH_ADD(fp24_pck(c, a)); + } + BENCH_END; + + BENCH_RUN("fp24_upk") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_pck(a, a); + BENCH_ADD(fp24_upk(c, a)); + } + BENCH_END; + fp24_free(a); fp24_free(b); fp24_free(c); + fp24_free(d[0]); + fp24_free(d[1]); bn_free(e); } diff --git a/contrib/relic/bench/bench_pc.c b/contrib/relic/bench/bench_pc.c index 8c4a476f3..ed805a953 100755 --- a/contrib/relic/bench/bench_pc.c +++ b/contrib/relic/bench/bench_pc.c @@ -303,7 +303,7 @@ static void memory2(void) { static void util2(void) { g2_t p, q; - uint8_t bin[4 * RLC_PC_BYTES + 1]; + uint8_t bin[8 * RLC_PC_BYTES + 1]; int l; g2_null(p); @@ -519,11 +519,13 @@ static void arith2(void) { } BENCH_END; +#if FP_PRIME != 509 BENCH_RUN("g2_map") { uint8_t msg[5]; rand_bytes(msg, 5); BENCH_ADD(g2_map(p, msg, 5)); } BENCH_END; +#endif g2_free(p); g2_free(q); diff --git a/contrib/relic/cmake/arch.cmake b/contrib/relic/cmake/arch.cmake index 5d41eaef1..0b9df7e28 100644 --- a/contrib/relic/cmake/arch.cmake +++ b/contrib/relic/cmake/arch.cmake @@ -24,31 +24,26 @@ message(" ALIGN=16 Align digit vectors into 128-bit boundaries.\n") # Architecture and memory layout. if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") set(ARCH "X86" CACHE STRING "Architecture") -endif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") -if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") +endif() +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") set(ARCH "X64" CACHE STRING "Architecture") -endif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") +endif() if(WORD AND NOT WSIZE) message(FATAL_ERROR "WORD has been replaced with WSIZE. Please update your configuration") endif() -if(ARCH STREQUAL X86) - set(AFLAGS "-m32") - set(WSIZE 32) -endif(ARCH STREQUAL X86) -if(ARCH STREQUAL X64) - set(AFLAGS "-m64") - set(WSIZE 64) -endif(ARCH STREQUAL X64) - if(NOT WSIZE) - if(MSVC) - set(WSIZE 32) - else(MSVC) - set(WSIZE 64) - endif(MSVC) -endif(NOT WSIZE) + if(ARCH STREQUAL X86) + set(AFLAGS "-m32") + set(WSIZE 32) + endif() + if(ARCH STREQUAL X64) + set(AFLAGS "-m64") + set(WSIZE 64) + endif() +endif() + set(WSIZE ${WSIZE} CACHE STRING "Processor word size") if(NOT ALIGN) diff --git a/contrib/relic/cmake/ep.cmake b/contrib/relic/cmake/ep.cmake index ec7670804..889887bc4 100644 --- a/contrib/relic/cmake/ep.cmake +++ b/contrib/relic/cmake/ep.cmake @@ -20,15 +20,16 @@ message(" EP_METHD=PROJC Homogeneous projective coordinates (complete fo message(" EP_METHD=JACOB Jacobian projective coordinates.\n") message(" Variable-base scalar multiplication:") -message(" EP_METHD=BASIC Binary method.") -message(" EP_METHD=LWNAF Left-to-right window NAF method (GLV for Koblitz curves).\n") +message(" EP_METHD=SLIDE Sliding window method.") +message(" EP_METHD=MONTY Montgomery ladder method.") +message(" EP_METHD=LWNAF Left-to-right window NAF method.") +message(" EP_METHD=LWREG Left-to-right regular recoding method (GLV for curves with endomorphisms).\n") message(" Fixed-base scalar multiplication:") message(" EP_METHD=BASIC Binary method for fixed point multiplication.") message(" EP_METHD=COMBS Single-table Comb method for fixed point multiplication.") message(" EP_METHD=COMBD Double-table Comb method for fixed point multiplication.") -message(" EP_METHD=LWNAF Left-to-right window NAF method (GLV for curves with endomorphisms).") -message(" EP_METHD=LWREG Left-to-right regular recoding method (GLV for curves with endomorphisms).\n") +message(" EP_METHD=LWNAF Left-to-right window NAF method (GLV for curves with endomorphisms).\n") message(" Variable-base simultaneous scalar multiplication:") message(" EP_METHD=BASIC Multiplication-and-addition simultaneous multiplication.") diff --git a/contrib/relic/cmake/fp.cmake b/contrib/relic/cmake/fp.cmake index 781e93635..720b94129 100644 --- a/contrib/relic/cmake/fp.cmake +++ b/contrib/relic/cmake/fp.cmake @@ -8,29 +8,29 @@ message(" FP_PMERS=[off|on] Prefer Pseudo-Mersenne primes over random prime message(" FP_QNRES=[off|on] Use -1 as quadratic non-residue (make sure that p = 3 mod 8).") message(" FP_WIDTH=w Width w in [2,6] of window processing for exponentiation methods.\n") -message(" ** Available prime field arithmetic methods (default = BASIC;COMBA;COMBA;MONTY;MONTY;SLIDE):") +message(" ** Available prime field arithmetic methods (default = BASIC;COMBA;COMBA;MONTY;MONTY;JMPDS;SLIDE):") -message(" Field addition") +message(" Field addition:") message(" FP_METHD=BASIC Schoolbook addition.") message(" FP_METHD=INTEG Integrated modular addition.\n") -message(" Field multiplication") +message(" Field multiplication:") message(" FP_METHD=BASIC Schoolbook multiplication.") message(" FP_METHD=INTEG Integrated modular multiplication.") message(" FP_METHD=COMBA Comba multiplication.\n") -message(" Field squaring") +message(" Field squaring:") message(" FP_METHD=BASIC Schoolbook squaring.") message(" FP_METHD=INTEG Integrated modular squaring.") message(" FP_METHD=COMBA Comba squaring.") message(" FP_METHD=MULTP Reuse multiplication for squaring.\n") -message(" Modular reduction") +message(" Modular reduction:") message(" FP_METHD=BASIC Division-based reduction.") message(" FP_METHD=QUICK Fast reduction modulo special form prime (2^t - c, c > 0).") message(" FP_METHD=MONTY Montgomery modular reduction.\n") -message(" Field inversion") +message(" Field inversion:") message(" FP_METHD=BASIC Inversion by Fermat's Little Theorem.") message(" FP_METHD=BINAR Binary Inversion algorithm.") message(" FP_METHD=MONTY Montgomery inversion.") @@ -38,7 +38,14 @@ message(" FP_METHD=EXGCD Inversion by the Extended Euclidean algorithm." message(" FP_METHD=DIVST Constant-time inversion by division steps.") message(" FP_METHD=LOWER Pass inversion to the lower level.\n") -message(" Field exponentiation") +message(" Legendre symbol:") +message(" FP_METHD=BASIC Computation by Fermat's Little Theorem.") +message(" FP_METHD=BINAR Binary algorithm.") +message(" FP_METHD=DIVST Constant-time method by division steps.") +message(" FP_METHD=JMPDS Constant-time method by jump division steps.") +message(" FP_METHD=LOWER Pass call to the lower level.\n") + +message(" Field exponentiation:") message(" FP_METHD=BASIC Binary exponentiation.") message(" FP_METHD=SLIDE Sliding window exponentiation.") message(" FP_METHD=MONTY Constant-time Montgomery powering ladder.\n") @@ -65,17 +72,18 @@ option(FP_QNRES "Use -1 as quadratic non-residue." off) # Choose the arithmetic methods. if (NOT FP_METHD) - set(FP_METHD "INTEG;INTEG;INTEG;MONTY;MONTY;SLIDE") + set(FP_METHD "INTEG;INTEG;INTEG;MONTY;MONTY;JMPDS;SLIDE") endif(NOT FP_METHD) list(LENGTH FP_METHD FP_LEN) -if (FP_LEN LESS 6) +if (FP_LEN LESS 7) message(FATAL_ERROR "Incomplete FP_METHD specification: ${FP_METHD}") -endif(FP_LEN LESS 6) +endif(FP_LEN LESS 7) list(GET FP_METHD 0 FP_ADD) list(GET FP_METHD 1 FP_MUL) list(GET FP_METHD 2 FP_SQR) list(GET FP_METHD 3 FP_RDC) list(GET FP_METHD 4 FP_INV) -list(GET FP_METHD 5 FP_EXP) +list(GET FP_METHD 5 FP_SMB) +list(GET FP_METHD 6 FP_EXP) set(FP_METHD ${FP_METHD} CACHE STRING "Method for prime field arithmetic.") diff --git a/contrib/relic/cmake/gmp.cmake b/contrib/relic/cmake/gmp.cmake index 01e32e989..abb00c44c 100644 --- a/contrib/relic/cmake/gmp.cmake +++ b/contrib/relic/cmake/gmp.cmake @@ -10,7 +10,7 @@ # 2. Redistributions in binary form must reproduce the copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products +# 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR @@ -38,17 +38,17 @@ endif (GMP_INCLUDE_DIR AND GMP_LIBRARIES) find_path(GMP_INCLUDE_DIR NAMES gmp.h) if(STBIN) - find_library(GMP_LIBRARIES NAMES libgmp.a gmp) + find_library(GMP_LIBRARIES NAMES libgmp.a gmp.lib libgmp-10 libgmp gmp) else(STBIN) - find_library(GMP_LIBRARIES NAMES libgmp.so gmp) + find_library(GMP_LIBRARIES NAMES libgmp.so gmp.lib libgmp-10 libgmp gmp) endif(STBIN) if(GMP_INCLUDE_DIR AND GMP_LIBRARIES) set(GMP_FOUND TRUE) -endif(GMP_INCLUDE_DIR AND GMP_LIBRARIES) +endif() if(GMP_FOUND) - message(STATUS "Configured GMP: ${GMP_LIBRARIES}") + message(STATUS "Configured GMP: -I${GMP_INCLUDE_DIR} -L${GMP_LIBRARIES}") else(GMP_FOUND) message(STATUS "Could NOT find GMP") endif(GMP_FOUND) diff --git a/contrib/relic/demo/ers-etrs/Makefile b/contrib/relic/demo/ers-etrs/Makefile new file mode 100644 index 000000000..5f625d7de --- /dev/null +++ b/contrib/relic/demo/ers-etrs/Makefile @@ -0,0 +1,13 @@ +CFLAGS=-O3 -march=native -mtune=native -ggdb +RELIC_ROOT = ../.. + +all: lib + gcc ${CFLAGS} -c test-bench.c -o test-bench.o -I ${RELIC_ROOT}/include -I target/include + gcc ${CFLAGS} -o test-bench test-bench.o target/lib/librelic_s.a -lgmp + +lib: + mkdir -p target + cd target; ${RELIC_ROOT}/../preset/x64-ecc-128.sh ${RELIC_ROOT}/../; cmake -DEP_METHD='JACOB;LWNAF;COMBS;INTER' -DEP_ENDOM=off -DBN_METHD=' COMBA;COMBA;MONTY;SLIDE;LEHME;BASIC' -DWITH="MD;BC;DV;BN;FP;EP;ED;EC;CP" .; make + +clean: + rm -rf target *.o test-bench diff --git a/contrib/relic/demo/ers-etrs/test-bench.c b/contrib/relic/demo/ers-etrs/test-bench.c new file mode 100644 index 000000000..796e62b70 --- /dev/null +++ b/contrib/relic/demo/ers-etrs/test-bench.c @@ -0,0 +1,333 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2009 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Benchmarks for cryptographic protocols. + * + * @version $Id$ + * @ingroup bench + */ + +#include + +#include "relic.h" +#include "relic_bench.h" + +#define MAX_KEYS 2048 + +#include "assert.h" + +static void ers(void) { + int size; + ec_t pp, pk[MAX_KEYS], *ptr; + bn_t sk[MAX_KEYS], td; + ers_t ring[MAX_KEYS]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + bn_null(td); + ec_null(pp); + + bn_new(td); + ec_new(pp); + for (int i = 0; i < MAX_KEYS; i++) { + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + ers_null(ring[i]); + ers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + bench_reset(); + for (int j = 0; j < BENCH; j++) { + BENCH_ADD(cp_ers_sig(td, ring[0], m, 5, sk[0], pk[0], pp)); + } + bench_compute(BENCH * BENCH); + util_print("{\"1\": {\"time\": %lf, \"size\": null}", bench_total()/(double)1000000); + + for (int j = 1; j < MAX_KEYS; j = j << 1) { + size = j; + bench_before(); + for (int k = 0; k < j; k++) { + cp_ers_ext(td, ring, &size, m, 5, pk[size], pp); + } + bench_after(); + bench_compute(1); + util_print(", \"%d\": {\"time\": %lf, \"size\": null}", size, bench_total()/(double)1000000); + assert(cp_ers_ver(td, ring, size, m, 5, pp)); + } + util_print("}\n\n"); + + /* Recompute the signature for verification. */ + cp_ers_sig(td, ring[0], m, 5, sk[0], pk[0], pp); + bench_reset(); + for (int j = 0; j < BENCH; j++) { + BENCH_ADD(assert(cp_ers_ver(td, ring, 1, m, 5, pp))); + } + bench_compute(BENCH * BENCH); + util_print("{\"1\": {\"time\": %lf, \"size\": %d}", bench_total()/(double)1000000, 9 * RLC_FP_BYTES); + + for (int j = 1; j < MAX_KEYS; j = j << 1) { + size = j; + /* Recompute the signatures for verification. */ + for (int k = 0; k < j; k++) { + assert(cp_ers_ext(td, ring, &size, m, 5, pk[size], pp) == RLC_OK); + } + assert(cp_ers_ver(td, ring, size, m, 5, pp)); + bench_reset(); + for (int i = 0; i < BENCH; i++) { + BENCH_ADD(cp_ers_ver(td, ring, size, m, 5, pp)); + } + bench_compute(BENCH * BENCH); + util_print(", \"%d\": {\"time\": %lf, \"size\": %d}", size, bench_total()/(double)1000000, size * 9 * RLC_FP_BYTES); + } + util_print("}"); + + bn_free(td); + ec_free(pp); + for (int i = 0; i < MAX_KEYS; i++) { + bn_free(sk[i]); + ec_free(pk[i]); + ers_free(ring[i]) + } +} + +static void smlers(void) { + int size; + ec_t pp, pk[MAX_KEYS], *ptr; + bn_t sk[MAX_KEYS], td[MAX_KEYS], y[MAX_KEYS]; + smlers_t ring[MAX_KEYS]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + ec_null(pp); + ec_new(pp); + for (int i = 0; i < MAX_KEYS; i++) { + bn_null(y[i]); + bn_new(y[i]); + bn_null(td[i]); + bn_new(td[i]); + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + smlers_null(ring[i]); + smlers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + for (int l = 1; l <= 8; l = l << 1) { + util_print("{"); + for (int j = l; j <= MAX_KEYS; j = j << 1) { + bench_reset(); + bench_before(); + size = 1; + for (int k = 0; k < l; k++) { + cp_smlers_sig(td[0], ring[0], m, 5, sk[0], pk[0], pp); + } + for (int k = l; k < j; k++) { + cp_smlers_ext(td[0], ring, &size, m, 5, pk[size], pp); + } + bench_after(); + bench_compute(1); + util_print("\"%d\": {\"time\": %lf, \"size\": null}", j, bench_total()/(double)1000000); + if (j < MAX_KEYS) { + util_print(", "); + } + for (int k = 0; k < l; k++) { + assert(cp_smlers_ver(td[0], ring, size, m, 5, pp)); + } + } + util_print("}\n\n"); + } + + for (int l = 1; l <= 8; l = l << 1) { + util_print("{"); + for (int j = l; j <= MAX_KEYS; j = j << 1) { + size = 1; + for (int k = 0; k < l; k++) { + cp_smlers_sig(td[0], ring[0], m, 5, sk[0], pk[0], pp); + } + for (int k = l; k < l; k++) { + cp_smlers_ext(td[0], ring, &size, m, 5, pk[size], pp); + } + bench_reset(); + bench_before(); + for (int i = 0; i < BENCH; i++) { + for (int k = 0; k < j; k++) { + cp_smlers_ver(td[0], ring, size, m, 5, pp); + } + } + bench_after(); + bench_compute(BENCH); + util_print("\"%d\": {\"time\": %lf, \"size\": null}", j, bench_total()/(double)1000000); + if (j < MAX_KEYS) { + util_print(", "); + } + } + util_print("}\n\n"); + } + + ec_free(pp); + for (int i = 0; i < MAX_KEYS; i++) { + bn_free(td[i]); + bn_free(y[i]); + bn_free(sk[i]); + ec_free(pk[i]); + smlers_free(ring[i]); + } +} + +#undef MAX_KEYS +#define MAX_KEYS 2048 +#define MIN_KEYS 64 + +static void etrs(void) { + int size; + ec_t pp, pk[MAX_KEYS], *ptr; + bn_t sk[MAX_KEYS], td[MAX_KEYS], y[MAX_KEYS]; + etrs_t ring[MAX_KEYS]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + ec_null(pp); + ec_new(pp); + for (int i = 0; i < MAX_KEYS; i++) { + bn_null(y[i]); + bn_new(y[i]); + bn_null(td[i]); + bn_new(td[i]); + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + ers_null(ring[i]); + ers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + util_print("{"); + bench_reset(); + for (int i = 0; i < BENCH; i++) { + BENCH_ADD(cp_etrs_sig(td, y, 1, ring[0], m, 5, sk[0], pk[0], pp)); + } + bench_compute(BENCH * BENCH); + util_print("\"1\": {\"time\": %lf, \"size\": null}", bench_total()/(double)1000000); + assert(cp_etrs_ver(1, td, y, 1, ring, 1, m, 5, pp)); + + for (int j = 2; j <= MAX_KEYS; j = j << 1) { + bench_reset(); + bench_before(); + for (int i = 0; i < BENCH; i++) { + cp_etrs_sig(td, y, j, ring[0], m, 5, sk[0], pk[0], pp); + } + bench_after(); + bench_compute(BENCH); + util_print(", \"%d\": {\"time\": %lf, \"size\": null}", j, bench_total()/(double)1000000); + assert(cp_etrs_ver(1, td, y, j, ring, 1, m, 5, pp)); + } + util_print("}\n\n"); + + for (int l = 2; l <= 8; l = l << 1) { + util_print("{"); + for (int j = l; j <= MAX_KEYS; j = j << 1) { + bench_reset(); + bench_before(); + size = 1; + cp_etrs_sig(td, y, j, ring[0], m, 5, sk[0], pk[0], pp); + for (int k = 1; k < j; k++) { + cp_etrs_ext(td, y, j, ring, &size, m, 5, pk[size], pp); + } + bench_after(); + bench_compute(1); + util_print("\"%d\": {\"time\": %lf, \"size\": null}", j, bench_total()/(double)1000000); + if (j < MAX_KEYS) { + util_print(", "); + } + assert(cp_etrs_ver(1, td+size-1, y+size-1, j-size+1, ring, size, m, 5, pp)); + } + util_print("}\n\n"); + } + + for (int l = 1; l <= 8; l = l << 1) { + util_print("{"); + for (int j = l; j <= MAX_KEYS; j = j << 1) { + size = 1; + cp_etrs_sig(td, y, j, ring[0], m, 5, sk[0], pk[0], pp); + for (int k = 0; k < l; k++) { + cp_etrs_ext(td, y, j, ring, &size, m, 5, pk[size], pp); + } + bench_reset(); + bench_before(); + for (int i = 0; i < BENCH; i++) { + cp_etrs_ver(1, td+size-1, y+size-1, j-size+1, ring, size, m, 5, pp); + } + bench_after(); + bench_compute(BENCH); + util_print("\"%d\": {\"time\": %lf, \"size\": null}", j, bench_total()/(double)1000000); + if (j < MAX_KEYS) { + util_print(", "); + } + } + util_print("}\n\n"); + } + + ec_free(pp); + for (int i = 0; i < MAX_KEYS; i++) { + bn_free(td[i]); + bn_free(y[i]); + bn_free(sk[i]); + ec_free(pk[i]); + etrs_free(ring[i]) + } +} + +int main(void) { + if (core_init() != RLC_OK) { + core_clean(); + return 1; + } + + conf_print(); + + if (ec_param_set_any() == RLC_OK) { + util_banner("ERS module", 1); + ers(); + util_banner("SMLERS module", 1); + smlers(); + util_banner("ETRS module", 1); + etrs(); + } else { + RLC_THROW(ERR_NO_CURVE); + } + + core_clean(); + return 0; +} diff --git a/contrib/relic/include/low/relic_bn_low.h b/contrib/relic/include/low/relic_bn_low.h index d8b4226e7..7c1747c0d 100644 --- a/contrib/relic/include/low/relic_bn_low.h +++ b/contrib/relic/include/low/relic_bn_low.h @@ -172,6 +172,18 @@ dig_t bn_rsh1_low(dig_t *c, const dig_t *a, int size); */ dig_t bn_rshb_low(dig_t *c, const dig_t *a, int size, int bits); +/** + * Shifts a signed digit vector to the right by an amount smaller than a digit. + * Computes c = a >> bits. + * + * @param[out] c - the result + * @param[in] a - the signed digit vector to shift. + * @param[in] size - the number of digits to shift. + * @param[in] bits - the shift amount. + * @return the carry of the last digit shift. + */ +dig_t bn_rshs_low(dig_t *c, const dig_t *a, int size, int bits); + /** * Multiplies a digit vector by a digit and adds this result to another digit * vector. Computes c = c + a * digit. @@ -196,6 +208,19 @@ dig_t bn_mula_low(dig_t *c, const dig_t *a, dig_t digit, int size); */ dig_t bn_mul1_low(dig_t *c, const dig_t *a, dig_t digit, int size); +/** + * Multiplies a signed digit vector by a signed digit and stores this result in + * another digit vector. Computes c = (-1)^sa * a * digit. + * + * @param[out] c - the result. + * @param[in] a - the first digit vector to multiply. + * @param[in] sa - the sign of the first digit vector. + * @param[in] digit - the digit to multiply. + * @param[in] size - the number of digits to multiply. + * @return the most significant digit. + */ +dig_t bn_muls_low(dig_t *c, const dig_t *a, dig_t sa, dis_t digit, int size); + /** * Multiplies two digit vectors of the same size. Computes c = a * b. * diff --git a/contrib/relic/include/low/relic_fp_low.h b/contrib/relic/include/low/relic_fp_low.h index cad9bb766..f31f305f0 100644 --- a/contrib/relic/include/low/relic_fp_low.h +++ b/contrib/relic/include/low/relic_fp_low.h @@ -321,6 +321,14 @@ void fp_rdcn_low(dig_t *c, dig_t *a); */ void fp_invm_low(dig_t *c, const dig_t *a); +/** + * Computes the Legendre symbol of a digit vector and the configured prime. + * + * @param[in] a - the digit vector to invert. + * @return the result. + */ +int fp_smbm_low(const dig_t *a); + #endif /* ASM */ #endif /* !RLC_FP_LOW_H */ diff --git a/contrib/relic/include/low/relic_fpx_low.h b/contrib/relic/include/low/relic_fpx_low.h index 41b8351d7..42cbf7b47 100644 --- a/contrib/relic/include/low/relic_fpx_low.h +++ b/contrib/relic/include/low/relic_fpx_low.h @@ -367,7 +367,7 @@ void fp3_mulm_low(fp3_t c, fp3_t a, fp3_t b); * @param[out] c - the result. * @param[in] a - the field element to square. */ -void fp3_sqrn_low(dv2_t c, fp3_t a); +void fp3_sqrn_low(dv3_t c, fp3_t a); /** * Squares a cubic extension field element with integrated modular diff --git a/contrib/relic/include/relic_bench.h b/contrib/relic/include/relic_bench.h index ceb841875..5d5167706 100644 --- a/contrib/relic/include/relic_bench.h +++ b/contrib/relic/include/relic_bench.h @@ -214,6 +214,6 @@ void bench_print(void); * * @return the last benchmark. */ -ull_t ben_total(void); +ull_t bench_total(void); #endif /* !RLC_BENCH_H */ diff --git a/contrib/relic/include/relic_bn.h b/contrib/relic/include/relic_bn.h index d99174058..1509700aa 100644 --- a/contrib/relic/include/relic_bn.h +++ b/contrib/relic/include/relic_bn.h @@ -148,11 +148,11 @@ typedef bn_st *bn_t; if ((A) == NULL) { \ RLC_THROW(ERR_NO_MEMORY); \ } \ - bn_init(A, RLC_BN_SIZE); \ + bn_make(A, RLC_BN_SIZE); \ #elif ALLOC == AUTO #define bn_new(A) \ - bn_init(A, RLC_BN_SIZE); \ + bn_make(A, RLC_BN_SIZE); \ #endif @@ -172,11 +172,11 @@ typedef bn_st *bn_t; if (A == NULL) { \ RLC_THROW(ERR_NO_MEMORY); \ } \ - bn_init(A, D); \ + bn_make(A, D); \ #elif ALLOC == AUTO #define bn_new_size(A, D) \ - bn_init(A, D); \ + bn_make(A, D); \ #endif @@ -374,7 +374,7 @@ typedef bn_st *bn_t; * @throw ERR_PRECISION - if the required precision cannot be represented * by the library. */ -void bn_init(bn_t a, int digits); +void bn_make(bn_t a, int digits); /** * Cleans a multiple precision integer. @@ -857,6 +857,17 @@ void bn_div_rem_dig(bn_t c, dig_t *d, const bn_t a, const dig_t b); */ void bn_mod_inv(bn_t c, const bn_t a, const bn_t b); +/** + * Computes the modular inverse of multiple precision integers simultaneously. + * Computes c_i such that a_i * c_i mod b = 1. + * + * @param[out] c - the results. + * @param[in] a - the elements to invert. + * param[in] b - the modulus. + * @param[in] n - the number of elements. + */ +void bn_mod_inv_sim(bn_t *c, const bn_t *a, const bn_t b, int n); + /** * Reduces a multiple precision integer modulo a power of 2. Computes * c = a mod 2^b. @@ -1145,20 +1156,22 @@ void bn_lcm(bn_t c, const bn_t a, const bn_t b); /** * Computes the Legendre symbol c = (a|b), b prime. * - * @param[out] c - the result. * @param[in] a - the first parameter. * @param[in] b - the second parameter. + * @throw ERR_NO_VALID - if there input is negative. + * @return the result. */ -void bn_smb_leg(bn_t c, const bn_t a, const bn_t b); +int bn_smb_leg(const bn_t a, const bn_t b); /** * Computes the Jacobi symbol c = (a|b). * - * @param[out] c - the result. * @param[in] a - the first parameter. * @param[in] b - the second parameter. + * @throw ERR_NO_VALID - if there input is even or negative. + * @return the result. */ -void bn_smb_jac(bn_t c, const bn_t a, const bn_t b); +int bn_smb_jac(const bn_t a, const bn_t b); /** * Returns a small precomputed prime from a given position in the list of prime @@ -1375,4 +1388,17 @@ void bn_rec_jsf(int8_t *jsf, int *len, const bn_t k, const bn_t l); void bn_rec_glv(bn_t k0, bn_t k1, const bn_t k, const bn_t n, const bn_t v1[], const bn_t v2[]); +/** + * Recodes a scalar in subscalars according to Frobenius endomorphism. + * + * @param[out] ki - the recoded subscalars. + * @param[in] sub - the number of subscalars. + * @param[in] k - the scalar to recode. + * @param[in] x - the elliptic curve parameter. + * @param[in] n - the elliptic curve group order. + * @param[in] bls - flag to indicate if it is a BLS12 curve. + */ +void bn_rec_frb(bn_t *ki, int sub, const bn_t k, const bn_t x, const bn_t n, + int bls); + #endif /* !RLC_BN_H */ diff --git a/contrib/relic/include/relic_conf.h.in b/contrib/relic/include/relic_conf.h.in index 7db6f5b50..b13c65223 100644 --- a/contrib/relic/include/relic_conf.h.in +++ b/contrib/relic/include/relic_conf.h.in @@ -254,11 +254,26 @@ #define EXGCD 4 /** Constant-time inversion by Bernstein-Yang division steps. */ #define DIVST 5 +/** Constant-time inversion by Bernstein-Yang jump division steps. */ +#define JMPDS 6 /** Use implementation provided by the lower layer. */ #define LOWER 8 /** Chosen prime field inversion method. */ #define FP_INV @FP_INV@ +/** Legendre by Fermat's Little Theorem. */ +#define BASIC 1 +/** Binary method. */ +#define BINAR 2 +/** Constant-time inversion by Bernstein-Yang division steps. */ +#define DIVST 5 +/** Constant-time inversion by Bernstein-Yang jump division steps. */ +#define JMPDS 6 +/** Use implementation provided by the lower layer. */ +#define LOWER 8 +/** Chosen prime field inversion method. */ +#define FP_SMB @FP_SMB@ + /** Binary modular exponentiation. */ #define BASIC 1 /** Sliding window modular exponentiation. */ @@ -671,8 +686,8 @@ #define DROID 5 /** Arduino platform. */ #define DUINO 6 -/** OpenBSD operating system. */ -#define OPENBSD 7 +/** NetBSD operating system. */ +#define NETBSD 7 /** Detected operation system. */ #cmakedefine OPSYS @OPSYS@ diff --git a/contrib/relic/include/relic_core.h b/contrib/relic/include/relic_core.h index eee9bc6a4..fa212d774 100644 --- a/contrib/relic/include/relic_core.h +++ b/contrib/relic/include/relic_core.h @@ -170,7 +170,7 @@ typedef struct _ctx_t { /** Square root of z. */ fb_st fb_srz; #ifdef FB_PRECO - /** Multiplication table for the z^(1/2). */ + /** Multiplication table for the polynomial z^(1/2). */ fb_st fb_tab_srz[256]; #endif /* FB_PRECO */ #endif /* FB_SRT == QUICK */ @@ -181,8 +181,6 @@ typedef struct _ctx_t { int chain_len; /** Tables for repeated squarings. */ fb_st fb_tab_sqr[RLC_TERMS][RLC_FB_TABLE]; - /** Pointers to the elements in the tables of repeated squarings. */ - fb_st *fb_tab_ptr[RLC_TERMS][RLC_FB_TABLE]; #endif /* FB_INV == ITOHT */ #endif /* WITH_FB */ @@ -230,6 +228,10 @@ typedef struct _ctx_t { /** Value of constant one in Montgomery form. */ bn_st one; #endif /* FP_RDC == MONTY */ +#if FP_INV == JUMPDS || !defined(STRIP) + /** Value of constant for divstep-based inversion. */ + bn_st inv; +#endif /* FP_INV */ /** Prime modulus modulo 8. */ dig_t mod8; /** Value derived from the prime used for modular reduction. */ @@ -317,6 +319,8 @@ typedef struct _ctx_t { fp2_t ep2_map_u; /** The constants needed for hashing. */ fp2_t ep2_map_c[4]; + /** The constants needed for Frobenius. */ + fp2_t ep2_frb[2]; /** Optimization identifier for the a-coefficient. */ int ep2_opt_a; /** Optimization identifier for the b-coefficient. */ @@ -335,6 +339,28 @@ typedef struct _ctx_t { /** The isogeny map coefficients for the SSWU mapping. */ iso2_st ep2_iso; #endif /* EP_CTMAP */ + /** The generator of the elliptic curve. */ + ep4_t ep4_g; + /** The 'a' coefficient of the curve. */ + fp4_t ep4_a; + /** The 'b' coefficient of the curve. */ + fp4_t ep4_b; + /** The order of the group of points in the elliptic curve. */ + bn_st ep4_r; + /** The cofactor of the group order in the elliptic curve. */ + bn_st ep4_h; + /** Optimization identifier for the a-coefficient. */ + int ep4_opt_a; + /** Optimization identifier for the b-coefficient. */ + int ep4_opt_b; + /** Flag that stores if the prime curve is a twist. */ + int ep4_is_twist; +#ifdef EP_PRECO + /** Precomputation table for generator multiplication.*/ + ep4_st ep4_pre[RLC_EP_TABLE]; + /** Array of pointers to the precomputation table. */ + ep4_st *ep4_ptr[RLC_EP_TABLE]; + #endif /* EP_PRECO */ #endif /* WITH_EPX */ #ifdef WITH_ED @@ -367,6 +393,7 @@ typedef struct _ctx_t { /** Constants for computing Frobenius maps in higher extensions. @{ */ fp2_st fp2_p1[5]; fp2_st fp2_p2[3]; + fp2_st fp4_p1; /** @} */ /** Constants for computing Frobenius maps in higher extensions. @{ */ int frb3[3]; diff --git a/contrib/relic/include/relic_cp.h b/contrib/relic/include/relic_cp.h index 2054feda3..47da43113 100644 --- a/contrib/relic/include/relic_cp.h +++ b/contrib/relic/include/relic_cp.h @@ -30,7 +30,7 @@ * * Interface of cryptographic protocols. * - * @ingroup bn + * @ingroup cp */ #ifndef RLC_CP_H @@ -38,6 +38,7 @@ #include "relic_conf.h" #include "relic_types.h" +#include "relic_util.h" #include "relic_bn.h" #include "relic_ec.h" #include "relic_pc.h" @@ -187,6 +188,78 @@ typedef bgn_st bgn_t[1]; typedef bgn_st *bgn_t; #endif +/** + * Represents an extendable ring signature. + */ +typedef struct _ers_st { + /** The ephemeral public key in the signature. */ + ec_t h; + /** The public key associated to the signature. */ + ec_t pk; + /** The first component of the signature of knowledge. */ + bn_t c[2]; + /** The second component of the signature of knowledge. */ + bn_t r[2]; +} ers_st; + +/** + * Pointer to an extendable ring signature. + */ +#if ALLOC == AUTO +typedef ers_st ers_t[1]; +#else +typedef ers_st *ers_t; +#endif + +/** + * Represents an extendable ring signature. + */ +typedef struct _smlers_st { + /** The extendable ring signature. */ + ers_t sig; + /** The linkability tag. */ + ec_t tau; + /** The first component of the signature of knowledge. */ + bn_t c[2]; + /** The second component of the signature of knowledge. */ + bn_t r[2]; +} smlers_st; + +/** + * Pointer to an extendable ring signature. + */ +#if ALLOC == AUTO +typedef smlers_st smlers_t[1]; +#else +typedef smlers_st *smlers_t; +#endif + +/** + * Represents an extendable threshold ring signature. + */ +typedef struct _etrs_st { + /** The secret. */ + bn_t y; + /** The ephemeral public key in the signature. */ + ec_t h; + /** The public key associated to the signature. */ + ec_t pk; + /** The first component of the signature of knowledge. */ + bn_t c[2]; + /** The second component of the signature of knowledge. */ + bn_t r[2]; +} etrs_st; + +/** + * Pointer to an extendable ring signature. + */ +#if ALLOC == AUTO +typedef etrs_st etrs_t[1]; +#else +typedef etrs_st *etrs_t; +#endif + + /*============================================================================*/ /* Macro definitions */ /*============================================================================*/ @@ -196,11 +269,7 @@ typedef bgn_st *bgn_t; * * @param[out] A - the moduli to initialize. */ -#if ALLOC == AUTO -#define crt_null(A) /* empty */ -#else -#define crt_null(A) A = NULL; -#endif +#define crt_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize a Rabin key pair. @@ -250,7 +319,7 @@ typedef bgn_st *bgn_t; } #elif ALLOC == AUTO -#define crt_free(A) /* empty */ +#define crt_free(A) /* empty */ #endif @@ -259,11 +328,7 @@ typedef bgn_st *bgn_t; * * @param[out] A - the key pair to initialize. */ -#if ALLOC == AUTO -#define rsa_null(A) /* empty */ -#else -#define rsa_null(A) A = NULL; -#endif +#define rsa_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize an RSA key pair. @@ -315,11 +380,7 @@ typedef bgn_st *bgn_t; * * @param[out] A - the key pair to initialize. */ -#if ALLOC == AUTO -#define rabin_null(A) /* empty */ -#else -#define rabin_null(A) A = NULL; -#endif +#define rabin_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize a Rabin key pair. @@ -340,11 +401,7 @@ typedef bgn_st *bgn_t; * * @param[out] A - the key pair to initialize. */ -#if ALLOC == AUTO -#define phpe_null(A) /* empty */ -#else -#define phpe_null(A) A = NULL; -#endif +#define phpe_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize a Paillier key pair. @@ -359,16 +416,13 @@ typedef bgn_st *bgn_t; * @param[out] A - the key pair to clean and free. */ #define phpe_free(A) crt_free(A) + /** * Initializes a Benaloh's key pair with a null value. * * @param[out] A - the key pair to initialize. */ -#if ALLOC == AUTO -#define bdpe_null(A) /* empty */ -#else -#define bdpe_null(A) A = NULL; -#endif +#define bdpe_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize a Benaloh's key pair. @@ -416,7 +470,6 @@ typedef bgn_st *bgn_t; #elif ALLOC == AUTO #define bdpe_free(A) /* empty */ - #endif /** @@ -424,11 +477,7 @@ typedef bgn_st *bgn_t; * * @param[out] A - the key pair to initialize. */ -#if ALLOC == AUTO -#define sokaka_null(A) /* empty */ -#else -#define sokaka_null(A) A = NULL; -#endif +#define sokaka_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize a SOKAKA key pair. @@ -446,7 +495,6 @@ typedef bgn_st *bgn_t; #elif ALLOC == AUTO #define sokaka_new(A) /* empty */ - #endif /** @@ -465,7 +513,6 @@ typedef bgn_st *bgn_t; #elif ALLOC == AUTO #define sokaka_free(A) /* empty */ - #endif /** @@ -473,11 +520,7 @@ typedef bgn_st *bgn_t; * * @param[out] A - the key pair to initialize. */ -#if ALLOC == AUTO -#define bgn_null(A) /* empty */ -#else -#define bgn_null(A) A = NULL; -#endif +#define bgn_null(A) RLC_NULL(A) /** * Calls a function to allocate and initialize a BGN key pair. @@ -502,7 +545,6 @@ typedef bgn_st *bgn_t; #elif ALLOC == AUTO #define bgn_new(A) /* empty */ - #endif /** @@ -528,7 +570,162 @@ typedef bgn_st *bgn_t; #elif ALLOC == AUTO #define bgn_free(A) /* empty */ +#endif + +/** + * Initializes a BGN key pair with a null value. + * + * @param[out] A - the key pair to initialize. + */ +#define ers_null(A) RLC_NULL(A) + +/** + * Calls a function to allocate and initialize an extendable signature ring. + * + * @param[out] A - the new signature ring. + */ +#if ALLOC == DYNAMIC +#define ers_new(A) \ + A = (ers_t)calloc(1, sizeof(ers_st)); \ + if (A == NULL) { \ + RLC_THROW(ERR_NO_MEMORY); \ + } \ + ec_new((A)->h); \ + ec_new((A)->pk); \ + bn_new((A)->c[0]); \ + bn_new((A)->c[1]); \ + bn_new((A)->r[0]); \ + bn_new((A)->r[1]); \ +#elif ALLOC == AUTO +#define ers_new(A) /* empty */ +#endif + +/** + * Calls a function to clean and free an extendable signature ring. + * + * @param[out] A - the signature ring to clean and free. + */ +#if ALLOC == DYNAMIC +#define ers_free(A) \ + if (A != NULL) { \ + ec_free((A)->h); \ + ec_free((A)->pk); \ + bn_free((A)->c[0]); \ + bn_free((A)->c[1]); \ + bn_free((A)->r[0]); \ + bn_free((A)->r[1]); \ + free(A); \ + A = NULL; \ + } + +#elif ALLOC == AUTO +#define ers_free(A) /* empty */ +#endif + +/** + * Initializes a BGN key pair with a null value. + * + * @param[out] A - the key pair to initialize. + */ +#define smlers_null(A) RLC_NULL(A) + +/** + * Calls a function to allocate and initialize an extendable signature ring. + * + * @param[out] A - the new signature ring. + */ +#if ALLOC == DYNAMIC +#define smlers_new(A) \ + A = (smlers_t)calloc(1, sizeof(ers_st)); \ + if (A == NULL) { \ + RLC_THROW(ERR_NO_MEMORY); \ + } \ + ers_new((A)->sig); \ + ec_new((A)->tau); \ + bn_new((A)->c[0]); \ + bn_new((A)->c[1]); \ + bn_new((A)->r[0]); \ + bn_new((A)->r[1]); \ + +#elif ALLOC == AUTO +#define smlers_new(A) /* empty */ +#endif + +/** + * Calls a function to clean and free an extendable signature ring. + * + * @param[out] A - the signature ring to clean and free. + */ +#if ALLOC == DYNAMIC +#define smlers_free(A) \ + if (A != NULL) { \ + ers_free((A)->sig); \ + ec_free((A)->tau); \ + bn_free((A)->c[0]); \ + bn_free((A)->c[1]); \ + bn_free((A)->r[0]); \ + bn_free((A)->r[1]); \ + free(A); \ + A = NULL; \ + } + +#elif ALLOC == AUTO +#define smlers_free(A) /* empty */ +#endif + +/** + * Initializes a BGN key pair with a null value. + * + * @param[out] A - the key pair to initialize. + */ +#define etrs_null(A) RLC_NULL(A) + +/** + * Calls a function to allocate and initialize an extendable signature ring. + * + * @param[out] A - the new signature ring. + */ +#if ALLOC == DYNAMIC +#define etrs_new(A) \ + A = (etrs_t)calloc(1, sizeof(etrs_st)); \ + if (A == NULL) { \ + RLC_THROW(ERR_NO_MEMORY); \ + } \ + bn_new((A)->y); \ + ec_new((A)->h); \ + ec_new((A)->pk); \ + bn_new((A)->c[0]); \ + bn_new((A)->c[1]); \ + bn_new((A)->r[0]); \ + bn_new((A)->r[1]); \ + +#elif ALLOC == AUTO +#define etrs_new(A) /* empty */ + +#endif + +/** + * Calls a function to clean and free an extendable signature ring. + * + * @param[out] A - the signature ring to clean and free. + */ +#if ALLOC == DYNAMIC +#define etrs_free(A) \ + if (A != NULL) { \ + bn_free((A)->y); \ + ec_free((A)->h); \ + ec_free((A)->pk); \ + bn_free((A)->c[0]); \ + bn_free((A)->c[1]); \ + bn_free((A)->r[0]); \ + bn_free((A)->r[1]); \ + free(A); \ + A = NULL; \ + } + +#elif ALLOC == AUTO +#define etrs_free(A) /* empty */ #endif /*============================================================================*/ @@ -569,8 +766,7 @@ int cp_rsa_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t pub); * @param[in] prv - the private key. * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ -int cp_rsa_dec(uint8_t *out, int *out_len, uint8_t *in, int in_len, - rsa_t prv); +int cp_rsa_dec(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv); /** * Signs using the basic RSA signature algorithm. The flag must be non-zero if @@ -586,7 +782,7 @@ int cp_rsa_dec(uint8_t *out, int *out_len, uint8_t *in, int in_len, * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_rsa_sig(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, - int hash, rsa_t prv); + int hash, rsa_t prv); /** * Verifies an RSA signature. The flag must be non-zero if the message being @@ -601,7 +797,7 @@ int cp_rsa_sig(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, * @return a boolean value indicating if the signature is valid. */ int cp_rsa_ver(uint8_t *sig, int sig_len, uint8_t *msg, int msg_len, int hash, - rsa_t pub); + rsa_t pub); /** * Generates a key pair for the Rabin cryptosystem. @@ -624,7 +820,7 @@ int cp_rabin_gen(rabin_t pub, rabin_t prv, int bits); * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_rabin_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, - rabin_t pub); + rabin_t pub); /** * Decrypts using the Rabin cryptosystem. @@ -637,7 +833,7 @@ int cp_rabin_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_rabin_dec(uint8_t *out, int *out_len, uint8_t *in, int in_len, - rabin_t prv); + rabin_t prv); /** * Generates a key pair for Benaloh's Dense Probabilistic Encryption. @@ -778,7 +974,7 @@ int cp_ecmqv_gen(bn_t d, ec_t q); * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_ecmqv_key(uint8_t *key, int key_len, bn_t d1, bn_t d2, ec_t q2u, - ec_t q1v, ec_t q2v); + ec_t q1v, ec_t q2v); /** * Generates an ECIES key pair. @@ -802,7 +998,7 @@ int cp_ecies_gen(bn_t d, ec_t q); * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_ecies_enc(ec_t r, uint8_t *out, int *out_len, uint8_t *in, int in_len, - ec_t q); + ec_t q); /** * Decrypts using the ECIES cryptosystem. @@ -816,7 +1012,7 @@ int cp_ecies_enc(ec_t r, uint8_t *out, int *out_len, uint8_t *in, int in_len, * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_ecies_dec(uint8_t *out, int *out_len, ec_t r, uint8_t *in, int in_len, - bn_t d); + bn_t d); /** * Generates an ECDSA key pair. @@ -887,6 +1083,228 @@ int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d); */ int cp_ecss_ver(bn_t e, bn_t s, uint8_t *msg, int len, ec_t q); +/** + * Generate parameters for the DCKKS pairing delegation protocol described at + * "Secure and Efficient Delegationof Pairings with Online Inputs" (CARDIS 2020) + * + * @param[out] c - the challenge. + * @param[out] r - the randomness. + * @param[out] u1 - the U1 precomputed value in G_1. + * @param[out] u2 - the U2 precomputed value in G_2. + * @param[out] v2 - the image of the randomness in G_2. + * @param[out] e - the precomputed values e(U1, U2). + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pdpub_gen(bn_t c, bn_t r, g1_t u1, g2_t u2, g2_t v2, gt_t e); + +/** + * Execute the client-side request for the DCKKS pairing delegation protocol. + * + * @param[out] v1 - the blinded element in G_1. + * @param[out] w2 - the blinded element in G_2. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] c - the challenge. + * @param[in] r - the randomness. + * @param[in] u1 - the U1 precomputed value in G_1. + * @param[in] u2 - the U2 precomputed value in G_2. + * @param[in] v2 - the image of the randomness in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pdpub_ask(g1_t v1, g2_t w2, g1_t p, g2_t q, bn_t c, bn_t r, g1_t u1, + g2_t u2, g2_t v2); + +/** + * Execute the server-side response for the DCKKS pairing delegation protocol. + * + * @param[out] g - the group elements computed by the server. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] v1 - the blinded element in G_1. + * @param[in] v2 - the image of the randomness in G_2. + * @param[in] w2 - the blinded element in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pdpub_ans(gt_t g[3], g1_t p, g2_t q, g1_t v1, g2_t v2, g2_t w2); + +/** + * Verifies the result of the DCKKS pairing delegation protocol. + * + * @param[out] r - the result of the computation. + * @param[in] g - the group elements returned by the server. + * @param[in] c - the challenge. + * @param[out] e - the precomputed values e(U1, U2). + * @return a boolean value indicating if the computation is correct. + */ +int cp_pdpub_ver(gt_t r, gt_t g[3], bn_t c, gt_t e); + +/** + * Generate parameters for the DCKKS pairing delegation protocol described at + * "Secure and Efficient Delegationof Pairings with Online Inputs" (CARDIS 2020) + * + * @param[out] c - the challenge. + * @param[out] r - the randomness. + * @param[out] u1 - the U1 precomputed value in G_1. + * @param[out] u2 - the U2 precomputed value in G_2. + * @param[out] v2 - the image of the randomness in G_2. + * @param[out] e - the precomputed values e(U1, U2). + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pdprv_gen(bn_t c, bn_t r[3], g1_t u1[2], g2_t u2[2], g2_t v2[4], + gt_t e[2]); + +/** + * Execute the client-side request for the DCKKS pairing delegation protocol. + * + * @param[out] v1 - the blinded element in G_1. + * @param[out] w2 - the blinded element in G_2. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] c - the challenge. + * @param[in] r - the randomness. + * @param[in] u1 - the U1 precomputed value in G_1. + * @param[in] u2 - the U2 precomputed value in G_2. + * @param[in] v2 - the image of the randomness in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pdprv_ask(g1_t v1[3], g2_t w2[4], g1_t p, g2_t q, bn_t c, bn_t r[3], + g1_t u1[2], g2_t u2[2], g2_t v2[4]); + +/** + * Execute the server-side response for the DCKKS pairing delegation protocol. + * + * @param[out] g - the group elements computed by the server. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] v1 - the blinded element in G_1. + * @param[in] v2 - the image of the randomness in G_2. + * @param[in] w2 - the blinded element in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pdprv_ans(gt_t g[4], g1_t v1[3], g2_t w2[4]); + +/** + * Verifies the result of the DCKKS pairing delegation protocol. + * + * @param[out] r - the result of the computation. + * @param[in] g - the group elements returned by the server. + * @param[in] c - the challenge. + * @param[out] e - the precomputed values e(U1, U2). + * @return a boolean value indicating if the computation is correct. + */ +int cp_pdprv_ver(gt_t r, gt_t g[4], bn_t c, gt_t e[2]); + +/** + * Generate parameters for the AMORE pairing delegation protocol with public + * inputs. + * + * @param[out] r - the randomness. + * @param[out] u1 - the U1 precomputed value in G_1. + * @param[out] u2 - the U2 precomputed value in G_2. + * @param[out] v2 - the image of the randomness in G_2. + * @param[out] e - the precomputed values e(U1, U2). + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_lvpub_gen(bn_t r, g1_t u1, g2_t u2, g2_t v2, gt_t e); + +/** + * Execute the client-side request for the AMORE pairing delegation protocol. + * + * @param[out] c - the challenge. + * @param[out] v1 - the blinded element in G_1. + * @param[out] w2 - the blinded element in G_2. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] c - the challenge. + * @param[in] r - the randomness. + * @param[in] u1 - the U1 precomputed value in G_1. + * @param[in] u2 - the U2 precomputed value in G_2. + * @param[in] v2 - the image of the randomness in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_lvpub_ask(bn_t c, g1_t v1, g2_t w2, g1_t p, g2_t q, bn_t r, g1_t u1, + g2_t u2, g2_t v2); + +/** + * Execute the server-side response for the AMORE pairing delegation protocol. + * + * @param[out] g - the group elements computed by the server. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] v1 - the blinded element in G_1. + * @param[in] v2 - the image of the randomness in G_2. + * @param[in] w2 - the blinded element in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_lvpub_ans(gt_t g[2], g1_t p, g2_t q, g1_t v1, g2_t v2, g2_t w2); + +/** + * Verifies the result of the AMORE pairing delegation protocol. + * + * @param[out] r - the result of the computation. + * @param[in] g - the group elements returned by the server. + * @param[in] c - the challenge. + * @param[out] e - the precomputed values e(U1, U2). + * @return a boolean value indicating if the computation is correct. + */ +int cp_lvpub_ver(gt_t r, gt_t g[2], bn_t c, gt_t e); + +/** + * Generate parameters for the AMORE pairing delegation protocol with private + * inputs. + * + * @param[out] c - the challenge. + * @param[out] r - the randomness. + * @param[out] u1 - the U1 precomputed value in G_1. + * @param[out] u2 - the U2 precomputed value in G_2. + * @param[out] v2 - the image of the randomness in G_2. + * @param[out] e - the precomputed values e(U1, U2). + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_lvprv_gen(bn_t c, bn_t r[3], g1_t u1[2], g2_t u2[2], g2_t v2[4], + gt_t e[2]); + +/** + * Execute the client-side request for the AMORE pairing delegation protocol. + * + * @param[out] v1 - the blinded element in G_1. + * @param[out] w2 - the blinded element in G_2. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] c - the challenge. + * @param[in] r - the randomness. + * @param[in] u1 - the U1 precomputed value in G_1. + * @param[in] u2 - the U2 precomputed value in G_2. + * @param[in] v2 - the image of the randomness in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_lvprv_ask(g1_t v1[3], g2_t w2[4], g1_t p, g2_t q, bn_t c, bn_t r[3], + g1_t u1[2], g2_t u2[2], g2_t v2[4]); + +/** + * Execute the server-side response for the AMORE pairing delegation protocol. + * + * @param[out] g - the group elements computed by the server. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] v1 - the blinded element in G_1. + * @param[in] v2 - the image of the randomness in G_2. + * @param[in] w2 - the blinded element in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_lvprv_ans(gt_t g[4], g1_t v1[3], g2_t w2[4]); + +/** + * Verifies the result of the AMORE pairing delegation protocol. + * + * @param[out] r - the result of the computation. + * @param[in] g - the group elements returned by the server. + * @param[in] c - the challenge. + * @param[out] e - the precomputed values e(U1, U2). + * @return a boolean value indicating if the computation is correct. + */ +int cp_lvprv_ver(gt_t r, gt_t g[4], bn_t c, gt_t e[2]); + /** * Generates a master key for the SOKAKA identity-based non-interactive * authenticated key agreement protocol. @@ -917,7 +1335,7 @@ int cp_sokaka_gen_prv(sokaka_t k, char *id, bn_t master); * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_sokaka_key(uint8_t *key, unsigned int key_len, char *id1, - sokaka_t k, char *id2); + sokaka_t k, char *id2); /** * Generates a key pair for the Boneh-Go-Nissim (BGN) cryptosystem. @@ -1030,7 +1448,7 @@ int cp_ibe_gen_prv(g2_t prv, char *id, bn_t master); * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_ibe_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, char *id, - g1_t pub); + g1_t pub); /** * Decrypts a message using the BF-IBE protocol. @@ -1372,7 +1790,7 @@ int cp_psb_gen(bn_t r, bn_t s[], g2_t g, g2_t x, g2_t y[], int l); * @param[in] l - the number of messages to sign. * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ -int cp_psb_sig(g1_t a, g1_t b, bn_t ms[], bn_t r, bn_t s[], int l); +int cp_psb_sig(g1_t a, g1_t b, bn_t ms[], bn_t r, bn_t s[], int l); /** * Verifies a block of messages signed using the PSB protocol. @@ -1416,7 +1834,7 @@ int cp_mpsb_gen(bn_t r[2], bn_t s[][2], g2_t h, g2_t x[2], g2_t y[][2], int l); * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_mpsb_sig(g1_t a, g1_t b[2], bn_t m[][2], bn_t r[2], bn_t s[][2], - mt_t mul_tri[2], mt_t sm_tri[2], int l); + mt_t mul_tri[2], mt_t sm_tri[2], int l); /** * Opens public values in the MPSS protocols, in this case public keys. @@ -1535,6 +1953,273 @@ int cp_vbnn_sig(ec_t r, bn_t z, bn_t h, uint8_t *id, int id_len, uint8_t *msg, int cp_vbnn_ver(ec_t r, bn_t z, bn_t h, uint8_t *id, int id_len, uint8_t *msg, int msg_len, ec_t mpk); +/** + * Computes the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Proves that y = [x]G. + * + * @param[out] c - the challenge. + * @param[out] r - the response. + * @param[in] y - the elliptic curve point + * @param[in] x - the discrete logarithm to prove. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pokdl_prv(bn_t c, bn_t r, ec_t y, bn_t x); + +/** + * Verifies the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Verifies that y = [x]G. + * + * @param[in] c - the challenge. + * @param[in] r - the response. + * @param[in] y - the elliptic curve point. + * @return a boolean value indicating the verification result. + */ +int cp_pokdl_ver(bn_t c, bn_t r, ec_t y); + +/** + * Computes the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Proves that y0 = [x]G or y[1] = [x]G. + * + * @param[out] c - the challenges. + * @param[out] r - the responses. + * @param[in] y - the elliptic curve points. + * @param[in] x - the discrete logarithm to prove. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_pokor_prv(bn_t c[2], bn_t r[2], ec_t y[2], bn_t x); + +/** + * Verifies the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Verifies that y = [x]G. + * + * @param[in] c - the challenges. + * @param[in] r - the responses. + * @param[in] y - the elliptic curve points. + * @return a boolean value indicating the verification result. + */ +int cp_pokor_ver(bn_t c[2], bn_t r[2], ec_t y[2]); + +/** + * Computes the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Proves that y = [x]G. + * + * @param[out] c - the challenge. + * @param[out] r - the response. + * @param[in] msg - the message to sign. + * @param[in] len - the length of the message. + * @param[in] y - the elliptic curve point + * @param[in] x - the discrete logarithm to prove. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_sokdl_sig(bn_t c, bn_t r, uint8_t *msg, int len, ec_t y, bn_t x); + +/** + * Verifies the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Verifies that y = [x]G. + * + * @param[in] c - the challenge. + * @param[in] r - the response. + * @param[in] msg - the message to sign. + * @param[in] len - the length of the message. + * @param[in] y - the elliptic curve point. + * @return a boolean value indicating the verification result. + */ +int cp_sokdl_ver(bn_t c, bn_t r, uint8_t *msg, int len, ec_t y); + +/** + * Computes the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Proves that y0 = [x]G or y1 = [x]G. + * + * @param[out] c - the challenges. + * @param[out] r - the responses. + * @param[in] msg - the message to sign. + * @param[in] len - the length of the message. + * @param[in] y - the elliptic curve points. + * @param[in] g - the elliptic curve generators. + * @param[in] x - the discrete logarithm to prove. + * @param[in] first - the flag to indicate the point for which the + * discrete logarithm is known. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_sokor_sig(bn_t c[2], bn_t r[2], uint8_t *msg, int len, ec_t y[2], + ec_t g[2], bn_t x, int first); + +/** + * Verifies the proof of knowledge of a discrete logarithm of an elliptic curve + * point to a generator. Verifies that y = [x]G. + * + * @param[in] c - the challenges. + * @param[in] r - the responses. + * @param[in] msg - the message to sign. + * @param[in] len - the length of the message. + * @param[in] y - the elliptic curve points. + * @param[in] g - the elliptic curve generators. + * @return a boolean value indicating the verification result. + */ +int cp_sokor_ver(bn_t c[2], bn_t r[2], uint8_t *msg, int len, ec_t y[2], + ec_t g[2]); + +/** + * Generates the public parameters of the extendable ring signature. + * + * @åaram[out] pp - the public parameters. + */ +int cp_ers_gen(ec_t pp); + +/** + * Generates a key pair for the extendable ring signature. + * + * @åaram[out] sk - the private key. + * @param[out] pk - the public key. + */ +int cp_ers_gen_key(bn_t sk, ec_t pk); + +/** + * Signs a message using the extendable ring signature scheme. + * + * @param[out] td - the signature trapdoor. + * @param[out] p - the resulting signature. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] sk - the signer's private key. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parameters. + */ +int cp_ers_sig(bn_t td, ers_t p, uint8_t *msg, int len, bn_t sk, ec_t pk, + ec_t pp); + +/** + * Verifies an extendable ring signature scheme over some messages. + * + * @param[in] td - the signature trapdoor. + * @param[in] s - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] pp - the public parameters. + */ +int cp_ers_ver(bn_t td, ers_t *s, int size, uint8_t *msg, int len, ec_t pp); + +/** + * Extends an extendable ring signature with a new signature. + * + * @param[in] td - the signature trapdoor. + * @param[in] p - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parameters. + */ +int cp_ers_ext(bn_t td, ers_t *p, int *size, uint8_t *msg, int len, ec_t pk, + ec_t pp); + +/** + * Signs a message using the same-message linkable extendable ring signature + * scheme. + * + * @param[out] td - the signature trapdoor. + * @param[out] p - the resulting signature. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] sk - the signer's private key. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parameters. + */ +int cp_smlers_sig(bn_t td, smlers_t p, uint8_t *msg, int len, bn_t sk, ec_t pk, + ec_t pp); + +/** + * Verifies a same-message linkable extendable ring signature. + * + * @param[in] td - the signature trapdoor. + * @param[in] s - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] pp - the public parameters. + */ +int cp_smlers_ver(bn_t td, smlers_t *s, int size, uint8_t *msg, int len, + ec_t pp); + +/** + * Extends a same-message extendable ring signature with a new signature. + * + * @param[in] td - the signature trapdoor. + * @param[in] p - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parameters. + */ +int cp_smlers_ext(bn_t td, smlers_t *p, int *size, uint8_t *msg, int len, + ec_t pk, ec_t pp); + +/** + * Signs a message using the extendable threshold ring signature scheme. + * + * @param[out] td - the signature trapdoors. + * @param[out] y - the signature randomness. + * @param[out] max - the maximum number of extensions. + * @param[out] p - the resulting signature. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] sk - the signer's private key. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parametetrs. + */ +int cp_etrs_sig(bn_t *td, bn_t *y, int max, etrs_t p, uint8_t *msg, int len, + bn_t sk, ec_t pk, ec_t pp); + +/** + * Verifies an extendable threshold ring signature scheme over some messages. + * + * @param[in] thres - the specified threshold. + * @param[in] td - the signature trapdoors. + * @param[in] y - the signature randomness. + * @param[in] max - the maximum number of extensions. + * @param[in] s - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] pp - the public parametetrs. + */ +int cp_etrs_ver(int thres, bn_t *td, bn_t *y, int max, etrs_t *s, int size, + uint8_t *msg, int len, ec_t pp); + +/** + * Extends an extendable threshold ring signature with a new signature. + * + * @param[in] td - the signature trapdoors. + * @param[in] y - the signature randomness. + * @param[in] max - the maximum number of extensions. + * @param[in] p - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parametetrs. + */ +int cp_etrs_ext(bn_t *td, bn_t *y, int max, etrs_t *p, int *size, uint8_t *msg, + int len, ec_t pk, ec_t pp); +/** + * Joins an extendable threshold ring signature with a new signature. + * + * @param[in] thres - the specified threshold. + * @param[in] td - the signature trapdoors. + * @param[in] y - the signature randomness. + * @param[in] max - the maximum number of extensions. + * @param[in] p - the ring of signatures. + * @param[in] size - the number of signatures in the ring. + * @param[in] msg - the message to sign. + * @param[in] len - the message length. + * @param[in] sk - the signer's private key. + * @param[in] pk - the singer's public key. + * @param[in] pp - the public parametetrs. + */ +int cp_etrs_uni(int thres, bn_t *td, bn_t *y, int max, etrs_t *p, int *size, + uint8_t *msg, int len, bn_t sk, ec_t pk, ec_t pp); /** * Initialize the Context-hiding Multi-key Homomorphic Signature scheme (CMLHS). * The scheme due to Schabhuser et al. signs a vector of messages. @@ -1633,7 +2318,7 @@ int cp_cmlhs_evl(g1_t r, g2_t s, g1_t rs[], g2_t ss[], dig_t f[], int len); * @return a boolean value indicating the verification result. */ int cp_cmlhs_ver(g1_t r, g2_t s, g1_t sig[], g2_t z[], g1_t a[], g1_t c[], - bn_t m, char *data, g1_t h, int label[], gt_t *hs[], + bn_t m, char *data, g1_t h, int label[], gt_t * hs[], dig_t *f[], int flen[], g2_t y[], g2_t pk[], int slen); /** @@ -1650,8 +2335,8 @@ int cp_cmlhs_ver(g1_t r, g2_t s, g1_t sig[], g2_t z[], g1_t a[], g1_t c[], * @param[in] slen - the number of signatures. * @return a boolean value indicating the verification result. */ -void cp_cmlhs_off(gt_t vk, g1_t h, int label[], gt_t *hs[], dig_t *f[], - int flen[], g2_t y[], g2_t pk[], int slen); +void cp_cmlhs_off(gt_t vk, g1_t h, int label[], gt_t * hs[], dig_t *f[], + int flen[], g2_t y[], g2_t pk[], int slen); /** * Perform the online verification of a CMLHS signature over a set of messages. @@ -1730,7 +2415,7 @@ int cp_mklhs_evl(g1_t sig, g1_t s[], dig_t f[], int len); * @return a boolean value indicating the verification result. */ int cp_mklhs_ver(g1_t sig, bn_t m, bn_t mu[], char *data, char *id[], - char *tag[], dig_t *f[], int flen[], g2_t pk[], int slen); + char *tag[], dig_t *f[], int flen[], g2_t pk[], int slen); /** * Computes the offline part of veryfying a MKLHS signature over a set of @@ -1746,7 +2431,7 @@ int cp_mklhs_ver(g1_t sig, bn_t m, bn_t mu[], char *data, char *id[], * @return RLC_OK if no errors occurred, RLC_ERR otherwise. */ int cp_mklhs_off(g1_t h[], dig_t ft[], char *id[], char *tag[], dig_t *f[], - int flen[], int slen); + int flen[], int slen); /** * Computes the online part of veryfying a MKLHS signature over a set of @@ -1764,6 +2449,57 @@ int cp_mklhs_off(g1_t h[], dig_t ft[], char *id[], char *tag[], dig_t *f[], * @return a boolean value indicating the verification result. */ int cp_mklhs_onv(g1_t sig, bn_t m, bn_t mu[], char *data, char *id[], g1_t h[], - dig_t ft[], g2_t pk[], int slen); + dig_t ft[], g2_t pk[], int slen); + +/** + * Generates the secrets and its consecutive powers for the Laconic Private Set + * Intersection (LaPSI) protocol, given the maximum set size. + * + * @param[out] sk - the sender's secret key. + * @param[out] ss - the secret power in G_2. + * @param[out] s - the consecutive powers in G_1. + * @param[in] m - the maximum set size. + */ +int cp_lapsi_gen(bn_t sk, g2_t ss, g1_t s[], int m); + +/** + * Computes the receiver part of the LaPSI protocol, given its input set. + * + * @param[out] d - the polynomial interpolation in the exponent. + * @param[out] r - the random nonce. + * @param[in] x - the receiver's input set. + * @param[in] s - the consecutive powers. + * @param[in] m - the receiver's input set size. + */ +int cp_lapsi_ask(g1_t d, bn_t r, bn_t x[], g1_t s[], int m); + +/** + * Computes the sender part of the LaPSI protocol, given its input set. + * + * @param[out] t - the pairing results. + * @param[out] u - the missing elements in the exponent. + * @param[in] d - the polynomial interpolation in the exponent. + * @param[in] ss - the secret power. + * @param[in] y - the server's input set. + * @param[in] n - the sender's input set size. + */ +int cp_lapsi_ans(gt_t t[], g2_t u[], g1_t d, g2_t ss, bn_t y[], int n); + +/** + * Computes the intersaction as the final part of the LaPSI protocol. + * + * @param[out] z - the elements in the intersection. + * @param[out] len - the cardinality of the resulting intersection. + * @param[in] sk - the sender's secret key. + * @param[in] d - the polynomial interpolation in the exponent. + * @param[in] x - the receiver's input set. + * @param[in] s - the consecutive powers. + * @param[in] m - the receiver's input set size. + * @param[in] t - the pairing results. + * @param[in] u - the missing elements in the exponent. + * @param[in] n - the sender's input set size. + */ +int cp_lapsi_int(bn_t z[], int *len, bn_t sk, g1_t d, bn_t x[], int m, + gt_t t[], g2_t u[], int n); #endif /* !RLC_CP_H */ diff --git a/contrib/relic/include/relic_eb.h b/contrib/relic/include/relic_eb.h index 20201af6f..b43650f1f 100644 --- a/contrib/relic/include/relic_eb.h +++ b/contrib/relic/include/relic_eb.h @@ -144,8 +144,12 @@ typedef struct { #if ALLOC == AUTO typedef eb_st eb_t[1]; #else +#ifdef CHECK +typedef eb_st *volatile eb_t; +#else typedef eb_st *eb_t; #endif +#endif /*============================================================================*/ /* Macro definitions */ diff --git a/contrib/relic/include/relic_ed.h b/contrib/relic/include/relic_ed.h index 911ea92f2..a458e4a00 100644 --- a/contrib/relic/include/relic_ed.h +++ b/contrib/relic/include/relic_ed.h @@ -80,7 +80,7 @@ enum { * Size of a precomputation table using the chosen algorithm. */ #if ED_FIX == BASIC -#define RLC_ED__TABLE RLC_ED_TABLE_BASIC +#define RLC_ED_TABLE RLC_ED_TABLE_BASIC #elif ED_FIX == COMBS #define RLC_ED_TABLE RLC_ED_TABLE_COMBS #elif ED_FIX == COMBD @@ -126,8 +126,12 @@ typedef struct { #if ALLOC == AUTO typedef ed_st ed_t[1]; #else +#ifdef CHECK +typedef ed_st *volatile ed_t; +#else typedef ed_st *ed_t; #endif +#endif /*============================================================================*/ /* Macro definitions */ diff --git a/contrib/relic/include/relic_ep.h b/contrib/relic/include/relic_ep.h index 71a157d53..bc9418d28 100644 --- a/contrib/relic/include/relic_ep.h +++ b/contrib/relic/include/relic_ep.h @@ -32,7 +32,7 @@ * * The scalar multiplication functions are only guaranteed to work * in the large prime order subgroup. If you need a generic scalar - * multiplication function, use ep_mul_basic(). + * multiplication function, use ep_mul_basic. * * @ingroup ep */ @@ -97,24 +97,28 @@ enum { BN_P254, /** Barreto-Naehrig curve with negative x. */ BN_P256, + /** Barreto-Naehrig curve standardized in China. */ + SM9_P256, /** Barreto-Lynn-Scott curve with embedding degree 12 (ZCash curve). */ B12_P381, /** Barreto-Naehrig curve with negative x. */ BN_P382, + /** Barreto-Lynn-Scott curve with embedding degree 12 (GT-strong). */ + B12_P383, /** Barreto-Naehrig curve with embedding degree 12. */ BN_P446, /** Barreto-Lynn-Scott curve with embedding degree 12. */ B12_P446, /** Barreto-Lynn-Scott curve with embedding degree 12. */ B12_P455, - /** Barreto-Lynn-Scott curve with embedding degree 24. */ - B24_P477, /** Kachisa-Schafer-Scott with negative x. */ KSS_P508, + /** Barreto-Lynn-Scott curve with embedding degree 24. */ + B24_P509, /** Optimal TNFS-secure curve with embedding degree 8. */ OT8_P511, /** Cocks-pinch curve with embedding degree 8. */ - CP8_P544, + GMT8_P544, /** Kachisa-Scott-Schaefer curve with embedding degree 54. */ K54_P569, /** Barreto-Lynn-Scott curve with embedding degree 48. */ @@ -142,7 +146,7 @@ enum { /* Optimal TNFS-secure. */ EP_OT8, /* Cocks-Pinch curve. */ - EP_CP8, + EP_GMT8, /* Barreto-Lynn-Scott with embedding degree 12. */ EP_B12, /* Kachisa-Schafer-Scott with embedding degree 16. */ @@ -235,15 +239,18 @@ typedef struct { int coord; } ep_st; - /** * Pointer to an elliptic curve point. */ #if ALLOC == AUTO typedef ep_st ep_t[1]; #else +#ifdef CHECK +typedef ep_st *volatile ep_t; +#else typedef ep_st *ep_t; #endif +#endif /** * Data structure representing an isogeny map. @@ -286,7 +293,7 @@ typedef iso_st *iso_t; * @param[out] A - the point to initialize. */ #if ALLOC == AUTO -#define ep_null(A) /* empty */ +#define ep_null(A) /* empty */ #else #define ep_null(A) A = NULL; #endif @@ -305,7 +312,7 @@ typedef iso_st *iso_t; } \ #elif ALLOC == AUTO -#define ep_new(A) /* empty */ +#define ep_new(A) /* empty */ #endif @@ -322,7 +329,7 @@ typedef iso_st *iso_t; } #elif ALLOC == AUTO -#define ep_free(A) /* empty */ +#define ep_free(A) /* empty */ #endif @@ -1141,14 +1148,15 @@ void ep_mul_sim_joint(ep_t r, const ep_t p, const bn_t k, const ep_t q, const bn_t m); /** - * Multiplies simultaneously elements from G_2. Computes R = \Sum_i=0..n k_iP_i. + * Multiplies and adds multiple elliptic curve points simultaneously. + * Computes R = \Sum_i=0..n [k_i]P_i. * * @param[out] r - the result. - * @param[out] p - the G_2 elements to multiply. + * @param[out] p - the elements to multiply. * @param[out] k - the integer scalars. * @param[out] n - the number of elements to multiply. */ -void ep_mul_sim_lot(ep_t r, ep_t p[], const bn_t k[], int n); +void ep_mul_sim_lot(ep_t r, const ep_t p[], const bn_t k[], int n); /** * Multiplies and adds the generator and a prime elliptic curve point @@ -1163,14 +1171,14 @@ void ep_mul_sim_gen(ep_t r, const bn_t k, const ep_t q, const bn_t m); /** * Multiplies prime elliptic curve points by small scalars. - * Computes R = \sum k_iP_i. + * Computes R = \Sum_i=0..n [k_i]P_i. * * @param[out] r - the result. * @param[in] p - the points to multiply. * @param[in] k - the small scalars. - * @param[in] len - the number of points to multiply. + * @param[in] n - the number of points to multiply. */ -void ep_mul_sim_dig(ep_t r, const ep_t p[], const dig_t k[], int len); +void ep_mul_sim_dig(ep_t r, const ep_t p[], const dig_t k[], int n); /** * Converts a point to affine coordinates. @@ -1190,25 +1198,25 @@ void ep_norm(ep_t r, const ep_t p); void ep_norm_sim(ep_t *r, const ep_t *t, int n); /** - * Maps a byte array to a point in a prime elliptic curve. - * + * Maps an array of uniformly random bytes to a point in a prime elliptic + * curve. + * That array is expected to have a length suitable for two field elements plus + * extra bytes for uniformity. + * * @param[out] p - the result. - * @param[in] msg - the byte array to map. + * @param[in] uniform_bytes - the array of uniform bytes to map. * @param[in] len - the array length in bytes. */ -void ep_map(ep_t p, const uint8_t *msg, int len); +void ep_map_from_field(ep_t p, const uint8_t *uniform_bytes, int len); /** - * Maps a byte array to a point in a prime elliptic curve using - * an explicit domain separation tag. + * Maps a byte array to a point in a prime elliptic curve. * * @param[out] p - the result. * @param[in] msg - the byte array to map. * @param[in] len - the array length in bytes. - * @param[in] dst - the domain separation tag. - * @param[in] dst_len - the domain separation tag length in bytes. */ -void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst_len); +void ep_map(ep_t p, const uint8_t *msg, int len); /** * Maps a byte array to a point in a prime elliptic curve with specified @@ -1220,7 +1228,8 @@ void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst * @param[in] dst - the domain separation tag. * @param[in] dst_len - the domain separation tag length in bytes. */ -void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst_len); +void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, + int dst_len); /** * Compresses a point. diff --git a/contrib/relic/include/relic_epx.h b/contrib/relic/include/relic_epx.h index 5162afeb7..f51f3ec7e 100644 --- a/contrib/relic/include/relic_epx.h +++ b/contrib/relic/include/relic_epx.h @@ -136,8 +136,8 @@ typedef struct { fp3_t y; /** The third coordinate (projective representation). */ fp3_t z; - /** Flag to indicate that this point is normalized. */ - int norm; + /** Flag to indicate the coordinate system of this point. */ + int coord; } ep3_st; /** @@ -149,6 +149,30 @@ typedef ep3_st ep3_t[1]; typedef ep3_st *ep3_t; #endif +/** + * Represents an elliptic curve point over a quartic extension over a prime + * field. + */ +typedef struct { + /** The first coordinate. */ + fp4_t x; + /** The second coordinate. */ + fp4_t y; + /** The third coordinate (projective representation). */ + fp4_t z; + /** Flag to indicate the coordinate system of this point. */ + int coord; +} ep4_st; + +/** + * Pointer to an elliptic curve point. + */ +#if ALLOC == AUTO +typedef ep4_st ep4_t[1]; +#else +typedef ep4_st *ep4_t; +#endif + /** * Coefficients of an isogeny map for a curve over a quadratic extension. */ @@ -189,11 +213,7 @@ typedef iso2_st *iso2_t; * * @param[out] A - the point to initialize. */ -#if ALLOC == AUTO -#define ep2_null(A) /* empty */ -#else -#define ep2_null(A) A = NULL -#endif +#define ep2_null(A) RLC_NULL(A) /** * Calls a function to allocate a point on an elliptic curve. @@ -238,6 +258,56 @@ typedef iso2_st *iso2_t; #define ep2_free(A) /* empty */ #endif +/** + * Initializes a point on an elliptic curve with a null value. + * + * @param[out] A - the point to initialize. + */ +#define ep4_null(A) RLC_NULL(A) + +/** + * Calls a function to allocate a point on an elliptic curve. + * + * @param[out] A - the new point. + * @throw ERR_NO_MEMORY - if there is no available memory. + */ +#if ALLOC == DYNAMIC +#define ep4_new(A) \ + A = (ep4_t)calloc(1, sizeof(ep4_st)); \ + if (A == NULL) { \ + RLC_THROW(ERR_NO_MEMORY); \ + } \ + fp4_null((A)->x); \ + fp4_null((A)->y); \ + fp4_null((A)->z); \ + fp4_new((A)->x); \ + fp4_new((A)->y); \ + fp4_new((A)->z); \ + +#elif ALLOC == AUTO +#define ep4_new(A) /* empty */ + +#endif + +/** + * Calls a function to clean and free a point on an elliptic curve. + * + * @param[out] A - the point to free. + */ +#if ALLOC == DYNAMIC +#define ep4_free(A) \ + if (A != NULL) { \ + fp4_free((A)->x); \ + fp4_free((A)->y); \ + fp4_free((A)->z); \ + free(A); \ + A = NULL; \ + } \ + +#elif ALLOC == AUTO +#define ep4_free(A) /* empty */ +#endif + /** * Adds two points in an elliptic curve over a quadratic extension field. * Computes R = P + Q. @@ -289,7 +359,7 @@ typedef iso2_st *iso2_t; #define ep2_mul(R, P, K) ep2_mul_slide(R, P, K) #elif EP_MUL == MONTY #define ep2_mul(R, P, K) ep2_mul_monty(R, P, K) -#elif EP_MUL == LWNAF || EP2_MUL == LWREG +#elif EP_MUL == LWNAF || EP_MUL == LWREG #define ep2_mul(R, P, K) ep2_mul_lwnaf(R, P, K) #endif @@ -350,6 +420,118 @@ typedef iso2_st *iso2_t; #define ep2_mul_sim(R, P, K, Q, M) ep2_mul_sim_joint(R, P, K, Q, M) #endif +/** + * Adds two points in an elliptic curve over a quadratic extension field. + * Computes R = P + Q. + * + * @param[out] R - the result. + * @param[in] P - the first point to add. + * @param[in] Q - the second point to add. + */ +#if EP_ADD == BASIC +#define ep4_add(R, P, Q) ep4_add_basic(R, P, Q); +#elif EP_ADD == PROJC || EP_ADD == JACOB +#define ep4_add(R, P, Q) ep4_add_projc(R, P, Q); +#endif + +/** + * Doubles a point in an elliptic curve over a quadratic extension field. + * Computes R = 2P. + * + * @param[out] R - the result. + * @param[in] P - the point to double. + */ +#if EP_ADD == BASIC +#define ep4_dbl(R, P) ep4_dbl_basic(R, P); +#elif EP_ADD == PROJC || EP_ADD == JACOB +#define ep4_dbl(R, P) ep4_dbl_projc(R, P); +#endif + +/** + * Multiplies a point in an elliptic curve over a quadratic extension field by + * an unrestricted integer scalar. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#define ep4_mul_big(R, P, K) ep4_mul_basic(R, P, K) + +/** + * Multiplies a point in an elliptic curve over a quadratic extension field. + * Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#if EP_MUL == BASIC +#define ep4_mul(R, P, K) ep4_mul_basic(R, P, K) +#elif EP_MUL == SLIDE +#define ep4_mul(R, P, K) ep4_mul_slide(R, P, K) +#elif EP_MUL == MONTY +#define ep4_mul(R, P, K) ep4_mul_monty(R, P, K) +#elif EP_MUL == LWNAF || EP_MUL == LWREG +#define ep4_mul(R, P, K) ep4_mul_lwnaf(R, P, K) +#endif + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * over a quadratic extension. + * + * @param[out] T - the precomputation table. + * @param[in] P - the point to multiply. + */ +#if EP_FIX == BASIC +#define ep4_mul_pre(T, P) ep4_mul_pre_basic(T, P) +#elif EP_FIX == COMBS +#define ep4_mul_pre(T, P) ep4_mul_pre_combs(T, P) +#elif EP_FIX == COMBD +#define ep4_mul_pre(T, P) ep4_mul_pre_combd(T, P) +#elif EP_FIX == LWNAF +//TODO: implement ep4_mul_pre_glv +#define ep4_mul_pre(T, P) ep4_mul_pre_lwnaf(T, P) +#endif + +/** + * Multiplies a fixed prime elliptic point over a quadratic extension using a + * precomputation table. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] T - the precomputation table. + * @param[in] K - the integer. + */ +#if EP_FIX == BASIC +#define ep4_mul_fix(R, T, K) ep4_mul_fix_basic(R, T, K) +#elif EP_FIX == COMBS +#define ep4_mul_fix(R, T, K) ep4_mul_fix_combs(R, T, K) +#elif EP_FIX == COMBD +#define ep4_mul_fix(R, T, K) ep4_mul_fix_combd(R, T, K) +#elif EP_FIX == LWNAF +//TODO: implement ep4_mul_fix_glv +#define ep4_mul_fix(R, T, K) ep4_mul_fix_lwnaf(R, T, K) +#endif + +/** + * Multiplies and adds two prime elliptic curve points simultaneously. Computes + * R = [k]P + [l]Q. + * + * @param[out] R - the result. + * @param[in] P - the first point to multiply. + * @param[in] K - the first integer. + * @param[in] Q - the second point to multiply. + * @param[in] M - the second integer, + */ +#if EP_SIM == BASIC +#define ep4_mul_sim(R, P, K, Q, M) ep4_mul_sim_basic(R, P, K, Q, M) +#elif EP_SIM == TRICK +#define ep4_mul_sim(R, P, K, Q, M) ep4_mul_sim_trick(R, P, K, Q, M) +#elif EP_SIM == INTER +#define ep4_mul_sim(R, P, K, Q, M) ep4_mul_sim_inter(R, P, K, Q, M) +#elif EP_SIM == JOINT +#define ep4_mul_sim(R, P, K, Q, M) ep4_mul_sim_joint(R, P, K, Q, M) +#endif + /*============================================================================*/ /* Function prototypes */ /*============================================================================*/ @@ -625,7 +807,7 @@ void ep2_add_projc(ep2_t r, ep2_t p, ep2_t q); * @param[in] p - the first point. * @param[in] q - the point to subtract. */ - void ep2_sub(ep2_t r, ep2_t p, ep2_t q); +void ep2_sub(ep2_t r, ep2_t p, ep2_t q); /** * Doubles a points represented in affine coordinates in an elliptic curve over @@ -942,6 +1124,18 @@ void ep2_norm(ep2_t r, ep2_t p); */ void ep2_norm_sim(ep2_t *r, ep2_t *t, int n); +/** + * Maps an array of uniformly random bytes to a point in a prime elliptic + * curve. + * That array is expected to have a length suitable for four field elements plus + * extra bytes for uniformity. + * + * @param[out] p - the result. + * @param[in] uniform_bytes - the array of uniform bytes to map. + * @param[in] len - the array length in bytes. + */ +void ep2_map_from_field(ep2_t p, const uint8_t *uniform_bytes, int len); + /** * Maps a byte array to a point in an elliptic curve over a quadratic extension. * @@ -994,4 +1188,632 @@ void ep2_pck(ep2_t r, ep2_t p); */ int ep2_upk(ep2_t r, ep2_t p); +/** + * Initializes the elliptic curve over quartic extension. + */ +void ep4_curve_init(void); + +/** + * Finalizes the elliptic curve over quartic extension. + */ +void ep4_curve_clean(void); + +/** + * Returns the 'a' coefficient of the currently configured elliptic curve. + * + * @return the 'a' coefficient of the elliptic curve. + */ +void ep4_curve_get_a(fp4_t a); + +/** + * Returns the 'b' coefficient of the currently configured elliptic curve. + * + * @param[out] b - the 'b' coefficient of the elliptic curve. + */ +void ep4_curve_get_b(fp4_t b); + +/** + * Returns the vector of coefficients required to perform GLV method. + * + * @param[out] b - the vector of coefficients. + */ +void ep4_curve_get_vs(bn_t *v); + +/** + * Returns a optimization identifier based on the 'a' coefficient of the curve. + * + * @return the optimization identifier. + */ +int ep4_curve_opt_a(void); + +/** + * Returns b optimization identifier based on the 'b' coefficient of the curve. + * + * @return the optimization identifier. + */ +int ep4_curve_opt_b(void); + +/** + * Tests if the configured elliptic curve is a twist. + * + * @return the type of the elliptic curve twist, 0 if non-twisted curve. + */ +int ep4_curve_is_twist(void); + +/** + * Returns the generator of the group of points in the elliptic curve. + * + * @param[out] g - the returned generator. + */ +void ep4_curve_get_gen(ep4_t g); + +/** + * Returns the precomputation table for the generator. + * + * @return the table. + */ +ep4_t *ep4_curve_get_tab(void); + +/** + * Returns the order of the group of points in the elliptic curve. + * + * @param[out] n - the returned order. + */ +void ep4_curve_get_ord(bn_t n); + +/** + * Returns the cofactor of the group order in the elliptic curve. + * + * @param[out] h - the returned cofactor. + */ +void ep4_curve_get_cof(bn_t h); + +/** + * Configures an elliptic curve over a quartic extension by its coefficients. + * + * @param[in] a - the 'a' coefficient of the curve. + * @param[in] b - the 'b' coefficient of the curve. + * @param[in] g - the generator. + * @param[in] r - the order of the group of points. + * @param[in] h - the cofactor of the group order. + */ +void ep4_curve_set(fp4_t a, fp4_t b, ep4_t g, bn_t r, bn_t h); + +/** + * Configures an elliptic curve by twisting the curve over the base prime field. + * + * @param - the type of twist (multiplicative or divisive) + */ +void ep4_curve_set_twist(int type); + +/** + * Tests if a point on an elliptic curve is at the infinity. + * + * @param[in] p - the point to test. + * @return 1 if the point is at infinity, 0 otherise. + */ +int ep4_is_infty(ep4_t p); + +/** + * Assigns an elliptic curve point to the point at infinity. + * + * @param[out] p - the point to assign. + */ +void ep4_set_infty(ep4_t p); + +/** + * Copies the second argument to the first argument. + * + * @param[out] q - the result. + * @param[in] p - the elliptic curve point to copy. + */ +void ep4_copy(ep4_t r, ep4_t p); + +/** + * Compares two elliptic curve points. + * + * @param[in] p - the first elliptic curve point. + * @param[in] q - the second elliptic curve point. + * @return RLC_EQ if p == q and RLC_NE if p != q. + */ +int ep4_cmp(ep4_t p, ep4_t q); + +/** + * Assigns a random value to an elliptic curve point. + * + * @param[out] p - the elliptic curve point to assign. + */ +void ep4_rand(ep4_t p); + +/** + * Randomizes coordinates of an elliptic curve point. + * + * @param[out] r - the blinded prime elliptic curve point. + * @param[in] p - the prime elliptic curve point to blind. + */ +void ep4_blind(ep4_t r, ep4_t p); + +/** + * Computes the right-hand side of the elliptic curve equation at a certain + * elliptic curve point. + * + * @param[out] rhs - the result. + * @param[in] p - the point. + */ +void ep4_rhs(fp4_t rhs, ep4_t p); + +/** + * Tests if a point is in the curve. + * + * @param[in] p - the point to test. + */ +int ep4_on_curve(ep4_t p); + +/** + * Builds a precomputation table for multiplying a random prime elliptic point. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + * @param[in] w - the window width. + */ +void ep4_tab(ep4_t *t, ep4_t p, int w); + +/** + * Prints an elliptic curve point. + * + * @param[in] p - the elliptic curve point to print. + */ +void ep4_print(ep4_t p); + +/** + * Returns the number of bytes necessary to store a prime elliptic curve point + * over a quartic extension with optional point compression. + * + * @param[in] a - the prime field element. + * @param[in] pack - the flag to indicate compression. + * @return the number of bytes. + */ +int ep4_size_bin(ep4_t a, int pack); + +/** + * Reads a prime elliptic curve point over a quartic extension from a byte + * vector in big-endian format. + * + * @param[out] a - the result. + * @param[in] bin - the byte vector. + * @param[in] len - the buffer capacity. + * @throw ERR_NO_VALID - if the encoded point is invalid. + * @throw ERR_NO_BUFFER - if the buffer capacity is invalid. + */ +void ep4_read_bin(ep4_t a, const uint8_t *bin, int len); + +/** + * Writes a prime elliptic curve pointer over a quartic extension to a byte + * vector in big-endian format with optional point compression. + * + * @param[out] bin - the byte vector. + * @param[in] len - the buffer capacity. + * @param[in] a - the prime elliptic curve point to write. + * @param[in] pack - the flag to indicate compression. + * @throw ERR_NO_BUFFER - if the buffer capacity is invalid. + */ +void ep4_write_bin(uint8_t *bin, int len, ep4_t a, int pack); + +/** + * Negates a point represented in affine coordinates in an elliptic curve over + * a quartic extension. + * + * @param[out] r - the result. + * @param[out] p - the point to negate. + */ +void ep4_neg(ep4_t r, ep4_t p); + +/** + * Adds to points represented in affine coordinates in an elliptic curve over a + * quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep4_add_basic(ep4_t r, ep4_t p, ep4_t q); + +/** + * Adds to points represented in affine coordinates in an elliptic curve over a + * quartic extension and returns the computed slope. + * + * @param[out] r - the result. + * @param[out] s - the slope. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep4_add_slp_basic(ep4_t r, fp4_t s, ep4_t p, ep4_t q); + +/** + * Adds two points represented in projective coordinates in an elliptic curve + * over a quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep4_add_projc(ep4_t r, ep4_t p, ep4_t q); + + /** + * Subtracts a point i an elliptic curve over a quartic extension from + * another. + * + * @param[out] r - the result. + * @param[in] p - the first point. + * @param[in] q - the point to subtract. + */ +void ep4_sub(ep4_t r, ep4_t p, ep4_t q); + +/** + * Doubles a points represented in affine coordinates in an elliptic curve over + * a quartic extension. + * + * @param[out] r - the result. + * @param[int] p - the point to double. + */ +void ep4_dbl_basic(ep4_t r, ep4_t p); + +/** + * Doubles a points represented in affine coordinates in an elliptic curve over + * a quartic extension and returns the computed slope. + * + * @param[out] r - the result. + * @param[out] s - the slope. + * @param[in] p - the point to double. + */ +void ep4_dbl_slp_basic(ep4_t r, fp4_t s, ep4_t p); + +/** + * Doubles a points represented in projective coordinates in an elliptic curve + * over a quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to double. + */ +void ep4_dbl_projc(ep4_t r, ep4_t p); + +/** + * Multiplies a prime elliptic point by an integer using the binary method. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +void ep4_mul_basic(ep4_t r, ep4_t p, const bn_t k); + +/** + * Multiplies a prime elliptic point by an integer using the sliding window + * method. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +void ep4_mul_slide(ep4_t r, ep4_t p, const bn_t k); + +/** + * Multiplies a prime elliptic point by an integer using the constant-time + * Montgomery ladder point multiplication method. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +void ep4_mul_monty(ep4_t r, ep4_t p, const bn_t k); + +/** + * Multiplies a prime elliptic point by an integer using the w-NAF method. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +void ep4_mul_lwnaf(ep4_t r, ep4_t p, const bn_t k); + +/** + * Multiplies a prime elliptic point by an integer using a regular method. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +void ep4_mul_lwreg(ep4_t r, ep4_t p, const bn_t k); + +/** + * Multiplies the generator of an elliptic curve over a qaudratic extension. + * + * @param[out] r - the result. + * @param[in] k - the integer. + */ +void ep4_mul_gen(ep4_t r, bn_t k); + +/** + * Multiplies a prime elliptic point by a small integer. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +void ep4_mul_dig(ep4_t r, ep4_t p, dig_t k); + + +/** + * Multiplies a point in an elliptic curve over a quartic extension field by + * the curve cofactor or a small multiple for which a short vector exists. + * In short, it takes a point in the curve to the large prime-order subgroup. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + */ +void ep4_mul_cof(ep4_t r, ep4_t p); + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * using the binary method. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + */ +void ep4_mul_pre_basic(ep4_t *t, ep4_t p); + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * using Yao's windowing method. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + */ +void ep4_mul_pre_yaowi(ep4_t *t, ep4_t p); + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * using the NAF windowing method. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + */ +void ep4_mul_pre_nafwi(ep4_t *t, ep4_t p); + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * using the single-table comb method. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + */ +void ep4_mul_pre_combs(ep4_t *t, ep4_t p); + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * using the double-table comb method. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + */ +void ep4_mul_pre_combd(ep4_t *t, ep4_t p); + +/** + * Builds a precomputation table for multiplying a fixed prime elliptic point + * using the w-(T)NAF method. + * + * @param[out] t - the precomputation table. + * @param[in] p - the point to multiply. + */ +void ep4_mul_pre_lwnaf(ep4_t *t, ep4_t p); + +/** + * Multiplies a fixed prime elliptic point using a precomputation table and + * the binary method. + * + * @param[out] r - the result. + * @param[in] t - the precomputation table. + * @param[in] k - the integer. + */ +void ep4_mul_fix_basic(ep4_t r, ep4_t *t, bn_t k); + +/** + * Multiplies a fixed prime elliptic point using a precomputation table and + * Yao's windowing method + * + * @param[out] r - the result. + * @param[in] t - the precomputation table. + * @param[in] k - the integer. + */ +void ep4_mul_fix_yaowi(ep4_t r, ep4_t *t, bn_t k); + +/** + * Multiplies a fixed prime elliptic point using a precomputation table and + * the w-(T)NAF method. + * + * @param[out] r - the result. + * @param[in] t - the precomputation table. + * @param[in] k - the integer. + */ +void ep4_mul_fix_nafwi(ep4_t r, ep4_t *t, bn_t k); + +/** + * Multiplies a fixed prime elliptic point using a precomputation table and + * the single-table comb method. + * + * @param[out] r - the result. + * @param[in] t - the precomputation table. + * @param[in] k - the integer. + */ +void ep4_mul_fix_combs(ep4_t r, ep4_t *t, bn_t k); + +/** + * Multiplies a fixed prime elliptic point using a precomputation table and + * the double-table comb method. + * + * @param[out] r - the result. + * @param[in] t - the precomputation table. + * @param[in] k - the integer. + */ +void ep4_mul_fix_combd(ep4_t r, ep4_t *t, bn_t k); + +/** + * Multiplies a fixed prime elliptic point using a precomputation table and + * the w-(T)NAF method. + * + * @param[out] r - the result. + * @param[in] t - the precomputation table. + * @param[in] k - the integer. + */ +void ep4_mul_fix_lwnaf(ep4_t r, ep4_t *t, bn_t k); + +/** + * Multiplies and adds two prime elliptic curve points simultaneously using + * scalar multiplication and point addition. + * + * @param[out] r - the result. + * @param[in] p - the first point to multiply. + * @param[in] k - the first integer. + * @param[in] q - the second point to multiply. + * @param[in] m - the second integer, + */ +void ep4_mul_sim_basic(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m); + +/** + * Multiplies and adds two prime elliptic curve points simultaneously using + * shamir's trick. + * + * @param[out] r - the result. + * @param[in] p - the first point to multiply. + * @param[in] k - the first integer. + * @param[in] q - the second point to multiply. + * @param[in] m - the second integer, + */ +void ep4_mul_sim_trick(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m); + +/** + * Multiplies and adds two prime elliptic curve points simultaneously using + * interleaving of NAFs. + * + * @param[out] r - the result. + * @param[in] p - the first point to multiply. + * @param[in] k - the first integer. + * @param[in] q - the second point to multiply. + * @param[in] m - the second integer, + */ +void ep4_mul_sim_inter(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m); + +/** + * Multiplies and adds two prime elliptic curve points simultaneously using + * Solinas' Joint Sparse Form. + * + * @param[out] r - the result. + * @param[in] p - the first point to multiply. + * @param[in] k - the first integer. + * @param[in] q - the second point to multiply. + * @param[in] m - the second integer, + */ +void ep4_mul_sim_joint(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m); + +/** + * Multiplies simultaneously elements from a prime elliptic curve. + * Computes R = \Sum_i=0..n k_iP_i. + * + * @param[out] r - the result. + * @param[out] p - the points to multiply. + * @param[out] k - the integer scalars. + * @param[out] n - the number of elements to multiply. + */ +void ep4_mul_sim_lot(ep4_t r, ep4_t p[], const bn_t k[], int n); + +/** + * Multiplies and adds the generator and a prime elliptic curve point + * simultaneously. Computes R = [k]G + [l]Q. + * + * @param[out] r - the result. + * @param[in] k - the first integer. + * @param[in] q - the second point to multiply. + * @param[in] m - the second integer, + */ +void ep4_mul_sim_gen(ep4_t r, bn_t k, ep4_t q, bn_t m); + +/** + * Multiplies prime elliptic curve points by small scalars. + * Computes R = \sum k_iP_i. + * + * @param[out] r - the result. + * @param[in] p - the points to multiply. + * @param[in] k - the small scalars. + * @param[in] len - the number of points to multiply. + */ +void ep4_mul_sim_dig(ep4_t r, ep4_t p[], dig_t k[], int len); + +/** + * Converts a point to affine coordinates. + * + * @param[out] r - the result. + * @param[in] p - the point to convert. + */ +void ep4_norm(ep4_t r, ep4_t p); + +/** + * Converts multiple points to affine coordinates. + * + * @param[out] r - the result. + * @param[in] t - the points to convert. + * @param[in] n - the number of points. + */ +void ep4_norm_sim(ep4_t *r, ep4_t *t, int n); + +/** + * Maps a byte array to a point in an elliptic curve over a quartic extension. + * + * @param[out] p - the result. + * @param[in] msg - the byte array to map. + * @param[in] len - the array length in bytes. + */ +void ep4_map(ep4_t p, const uint8_t *msg, int len); + +/** + * Maps a byte array to a point in an elliptic curve over a quartic extension + * using an explicit domain separation tag. + * + * @param[out] p - the result. + * @param[in] msg - the byte array to map. + * @param[in] len - the array length in bytes. + * @param[in] dst - the domain separatoin tag. + * @param[in] dst_len - the domain separation tag length in bytes. + */ +void ep4_map_dst(ep4_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst_len); + +/** + * Computes a power of the Gailbraith-Lin-Scott homomorphism of a point + * represented in affine coordinates on a twisted elliptic curve over a + * quartic exension. That is, Psi^i(P) = Twist(P)(Frob^i(unTwist(P)). + * On the trace-zero group of a quartic twist, consists of a power of the + * Frobenius map of a point represented in affine coordinates in an elliptic + * curve over a quartic exension. Computes Frob^i(P) = (p^i)P. + * + * @param[out] r - the result in affine coordinates. + * @param[in] p - a point in affine coordinates. + * @param[in] i - the power of the Frobenius map. + */ +void ep4_frb(ep4_t r, ep4_t p, int i); + +/** + * Compresses a point in an elliptic curve over a quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to compress. + */ +void ep4_pck(ep4_t r, ep4_t p); + +/** + * Decompresses a point in an elliptic curve over a quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to decompress. + * @return if the decompression was successful + */ +int ep4_upk(ep4_t r, ep4_t p); + #endif /* !RLC_EPX_H */ diff --git a/contrib/relic/include/relic_err.h b/contrib/relic/include/relic_err.h index 55596f617..e16f71fe0 100644 --- a/contrib/relic/include/relic_err.h +++ b/contrib/relic/include/relic_err.h @@ -71,6 +71,8 @@ enum errors { ERR_NO_CURVE, /** Occurs when the library configuration is incorrect. */ ERR_NO_CONFIG, + /** Occurs when the PRNG is stuck at one value. */ + ERR_NO_RAND, /** Constant to indicate the number of errors. */ ERR_MAX }; @@ -160,9 +162,9 @@ typedef struct _sts_t { /** * Implements the THROW clause of the error-handling routines. * - * If the error pointer is not NULL but there is no surrounding TRY-CATCH - * block, then the code threw an exception after an exception was thrown. - * In this case, we finish execution. + * First we make sure that the error pointer is NULL (new exception) or + * there is a surrounding try-catch block (block = 1). If this is not the case, + * then it is the second exception thrown in sequence without handling. * * If the error pointer is NULL, the error was thrown outside of a TRY-CATCH * block. An error message is printed and the function returns. @@ -178,21 +180,20 @@ typedef struct _sts_t { { \ ctx_t *_ctx = core_get(); \ _ctx->code = RLC_ERR; \ - if (_ctx->last != NULL && _ctx->last->block == 0) { \ - exit(E); \ - } \ - if (_ctx->last == NULL) { \ - _ctx->last = &(_ctx->error); \ - _ctx->error.error = &(_ctx->number); \ - _ctx->error.block = 0; \ - _ctx->number = E; \ - RLC_ERR_PRINT(E); \ - } else { \ - for (; ; longjmp(_ctx->last->addr, 1)) { \ + if (_ctx->last == NULL || _ctx->last->block == 1) { \ + if (_ctx->last == NULL) { \ + _ctx->last = &(_ctx->error); \ + _ctx->error.error = &(_ctx->number); \ + _ctx->error.block = 0; \ + _ctx->number = E; \ RLC_ERR_PRINT(E); \ - if (_ctx->last->error) { \ - if (E != ERR_CAUGHT) { \ - *(_ctx->last->error) = E; \ + } else { \ + for (; ; longjmp(_ctx->last->addr, 1)) { \ + RLC_ERR_PRINT(E); \ + if (_ctx->last->error) { \ + if (E != ERR_CAUGHT) { \ + *(_ctx->last->error) = E; \ + } \ } \ } \ } \ @@ -261,7 +262,7 @@ typedef struct _sts_t { #else #define RLC_THROW(E) \ core_get()->code = RLC_ERR; \ - util_print("FATAL ERROR in %s:%d\n", RLC_FILE, __LINE__); \ + util_print("ERROR THROWN in %s:%d\n", RLC_FILE, __LINE__); \ #endif #endif diff --git a/contrib/relic/include/relic_fb.h b/contrib/relic/include/relic_fb.h index caa0bcb6a..48fe45b80 100644 --- a/contrib/relic/include/relic_fb.h +++ b/contrib/relic/include/relic_fb.h @@ -435,7 +435,7 @@ const dig_t *fb_poly_tab_srz(int i); * @param the number of the table. * @return the precomputed result. */ -const fb_t *fb_poly_tab_sqr(int i); +const fb_st *fb_poly_tab_sqr(int i); /** * Returns an addition chain for (RLC_FB_BITS - 1). @@ -973,7 +973,7 @@ void fb_itr_basic(fb_t c, const fb_t a, int b); * @param[out] t - the precomputed table. * @param[in] b - the exponent. */ -void fb_itr_pre_quick(fb_t *t, int b); +void fb_itr_pre_quick(fb_st *t, int b); /** * Computes the iterated squaring/square-root of a binary field element by @@ -983,6 +983,6 @@ void fb_itr_pre_quick(fb_t *t, int b); * @param[in] a - the basis. * @param[in] t - the precomputed table. */ -void fb_itr_quick(fb_t c, const fb_t a, const fb_t *t); +void fb_itr_quick(fb_t c, const fb_t a, const fb_st *t); #endif /* !RLC_FB_H */ diff --git a/contrib/relic/include/relic_fp.h b/contrib/relic/include/relic_fp.h index 4fb779c4b..fbbd3fc5f 100644 --- a/contrib/relic/include/relic_fp.h +++ b/contrib/relic/include/relic_fp.h @@ -98,6 +98,8 @@ enum { PRIME_383187, /** NIST 384-bit fast reduction polynomial. */ NIST_384, + /** Curve448 prime. */ + PRIME_448, /** Curve511187 511-bit prime modulus. */ PRIME_511187, /** NIST 521-bit fast reduction polynomial. */ @@ -108,10 +110,14 @@ enum { BN_254, /** 256-bit prime provided in Barreto et al. for BN curves. */ BN_256, + /** 256-bit prime provided for BN curve standardized in China. */ + SM9_256, /** 381-bit prime for BLS curve of embedding degree 12 (Zcash). */ B12_381, /** 382-bit prime provided by Barreto for BN curve. */ BN_382, + /** 383-bit prime for GT-strong BLS curve of embedding degree 12. */ + B12_383, /** 446-bit prime provided by Barreto for BN curve. */ BN_446, /** 446-bit prime for BLS curve of embedding degree 12. */ @@ -119,13 +125,13 @@ enum { /** 455-bit prime for BLS curve of embedding degree 12. */ B12_455, /** 477-bit prime for BLS curve of embedding degree 24. */ - B24_477, + B24_509, /** 508-bit prime for KSS16 curve. */ KSS_508, /** 511-bit prime for Optimal TNFS-secure curve. */ OT_511, /** Random 544-bit prime for Cocks-Pinch curve with embedding degree 8. */ - CP8_544, + GMT8_544, /** 569-bit prime for KSS curve with embedding degree 54. */ K54_569, /** 575-bit prime for BLS curve with embedding degree 48. */ @@ -354,10 +360,30 @@ typedef rlc_align dig_t fp_st[RLC_FP_DIGS + RLC_PAD(RLC_FP_BYTES)/(RLC_DIG / 8)] #define fp_inv(C, A) fp_inv_exgcd(C, A) #elif FP_INV == DIVST #define fp_inv(C, A) fp_inv_divst(C, A) +#elif FP_INV == JMPDS +#define fp_inv(C, A) fp_inv_jmpds(C, A) #elif FP_INV == LOWER #define fp_inv(C, A) fp_inv_lower(C, A) #endif +/** + * Computes the Legendre symbol of a prime field element. Computes C = (A|P). + * + * @param[out] C - the result. + * @param[in] A - the prime field element to compute. + */ +#if FP_SMB == BASIC +#define fp_smb(A) fp_smb_basic(A) +#elif FP_SMB == BINAR +#define fp_smb(A) fp_smb_binar(A) +#elif FP_SMB == DIVST +#define fp_smb(A) fp_smb_divst(A) +#elif FP_SMB == JMPDS +#define fp_smb(A) fp_smb_jmpds(A) +#elif FP_SMB == LOWER +#define fp_smb(A) fp_smb_lower(A) +#endif + /** * Exponentiates a prime field element. Computes C = A^B (mod p). * @@ -1023,6 +1049,16 @@ void fp_inv_exgcd(fp_t c, const fp_t a); */ void fp_inv_divst(fp_t c, const fp_t a); +/** + * Inverts a prime field element using the constant-time jump division step + * by Bernstein and Bo-Yin Yang. + * + * @param[out] c - the result. + * @param[in] a - the prime field element to invert. + * @throw ERR_NO_VALID - if the field element is not invertible. + */ +void fp_inv_jmpds(fp_t c, const fp_t a); + /** * Inverts a prime field element using a direct call to the lower layer. * @@ -1041,6 +1077,49 @@ void fp_inv_lower(fp_t c, const fp_t a); */ void fp_inv_sim(fp_t *c, const fp_t *a, int n); +/** + * Computes Legendre symbol of a prime field element using exponentiation. + * + * @param[in] a - the prime field element to compute. + * @return the result. + */ +int fp_smb_basic(const fp_t a); + +/** + * Computes Legendre symbol of a prime field element using the binary method. + * + * @param[in] a - the prime field element to compute. + * @return the result. + */ +int fp_smb_binar(const fp_t a); + +/** + * Computes Legendre symbol of a prime field element using the constant-time + * division step approach by Bernstein and Bo-Yin Yang. + * + * @param[in] a - the prime field element to compute. + * @return the result. + */ +int fp_smb_divst(const fp_t a); + +/** + * Computes Legendre symbol of a prime field element using the constant-time + * jump division step approach by Bernstein and Bo-Yin Yang. + * + * @param[in] a - the prime field element to compute. + * @return the result. + */ +int fp_smb_jmpds(const fp_t a); + +/** + * Computes Legendre symbol a prime field element using a direct call to the + * lower layer. + * + * @param[in] a - the prime field element to invert. + * @return the result. + */ +int fp_smb_lower(const fp_t a); + /** * Exponentiates a prime field element using the binary * method. diff --git a/contrib/relic/include/relic_fpx.h b/contrib/relic/include/relic_fpx.h index c1d623664..f1f139ca1 100644 --- a/contrib/relic/include/relic_fpx.h +++ b/contrib/relic/include/relic_fpx.h @@ -1038,6 +1038,32 @@ void fp2_sub_dig(fp2_t c, const fp2_t a, dig_t b); #define fp24_sqr(C, A) fp24_sqr_lazyr(C, A) #endif +/** + * Squares a 24-degree extension field element in the cyclotomic subgroup. + * Computes C = A * A. + * + * @param[out] C - the result. + * @param[in] A - the 24-degree extension field element to square. + */ +#if FPX_RDC == BASIC +#define fp24_sqr_cyc(C, A) fp24_sqr_cyc_basic(C, A) +#elif FPX_RDC == LAZYR +#define fp24_sqr_cyc(C, A) fp24_sqr_cyc_lazyr(C, A) +#endif + +/** + * Squares a 24-degree extension field element in the cyclotomic subgroup in + * compressed form. Computes C = A * A. + * + * @param[out] C - the result. + * @param[in] A - the 24-degree extension field element to square. + */ +#if FPX_RDC == BASIC +#define fp24_sqr_pck(C, A) fp24_sqr_pck_basic(C, A) +#elif FPX_RDC == LAZYR +#define fp24_sqr_pck(C, A) fp24_sqr_pck_lazyr(C, A) +#endif + /** * Initializes a double-precision 48-degree extension field with null. * @@ -1870,6 +1896,11 @@ void fp3_frb(fp3_t c, fp3_t a, int i); */ int fp3_srt(fp3_t c, fp3_t a); +/** + * Initializes the quartic extension field arithmetic module. + */ +void fp4_field_init(void); + /** * Copies the second argument to the first argument. * @@ -2037,6 +2068,17 @@ void fp4_mul_lazyr(fp4_t c, fp4_t a, fp4_t b); */ void fp4_mul_art(fp4_t c, fp4_t a); +/** + * Multiplies a quartic extension field element by a power of the constant + * needed to compute a power of the Frobenius map. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + * @param[in] i - the power of the Frobenius map. + * @param[in] j - the power of the constant. + */ +void fp4_mul_frb(fp4_t c, fp4_t a, int i, int j); + /** * Multiples a dense quartic extension field element by a sparse element. * @@ -2053,7 +2095,7 @@ void fp4_mul_dxs(fp4_t c, fp4_t a, fp4_t b); * @param[out] c - the result. * @param[in] a - the quartic extension field element to square. */ -void fp4_sqr_unr(dv6_t c, fp4_t a); +void fp4_sqr_unr(dv4_t c, fp4_t a); /** * Computes the squares of a quartic extension field element using basic @@ -2080,6 +2122,15 @@ void fp4_sqr_lazyr(fp4_t c, fp4_t a); */ void fp4_inv(fp4_t c, fp4_t a); +/** + * Inverts multiple quartic extension field elements simultaneously. + * + * @param[out] c - the result. + * @param[in] a - the quartic extension field elements to invert. + * @param[in] n - the number of elements. + */ +void fp4_inv_sim(fp4_t *c, fp4_t *a, int n); + /** * Computes the inverse of a cyclotomic quartic extension field element. * @@ -2110,6 +2161,16 @@ void fp4_exp(fp4_t c, fp4_t a, bn_t b); */ void fp4_frb(fp4_t c, fp4_t a, int i); +/** + * Extracts the square root of a quartic extension field element. Computes + * c = sqrt(a). The other square root is the negation of c. + * + * @param[out] c - the result. + * @param[in] a - the extension field element. + * @return - 1 if there is a square root, 0 otherwise. + */ +int fp4_srt(fp4_t c, fp4_t a); + /** * Copies the second argument to the first argument. * @@ -3582,9 +3643,10 @@ void fp24_print(fp24_t a); * element. * * @param[in] a - the extension field element. + * @param[in] pack - the flag to indicate compression. * @return the number of bytes. */ -int fp24_size_bin(fp24_t a); +int fp24_size_bin(fp24_t a, int pack); /** * Reads a 24-degree extension field element from a byte vector in big-endian @@ -3604,9 +3666,10 @@ void fp24_read_bin(fp24_t a, const uint8_t *bin, int len); * @param[out] bin - the byte vector. * @param[in] len - the buffer capacity. * @param[in] a - the extension field element to write. + * @param[in] pack - the flag to indicate compression. * @throw ERR_NO_BUFFER - if the buffer capacity is not correct. */ -void fp24_write_bin(uint8_t *bin, int len, fp24_t a); +void fp24_write_bin(uint8_t *bin, int len, fp24_t a, int pack); /** * Returns the result of a comparison between two 24-degree extension field @@ -3743,6 +3806,84 @@ void fp24_sqr_basic(fp24_t c, fp24_t a); */ void fp24_sqr_lazyr(fp24_t c, fp24_t a); +/** + * Computes the square of a cyclotomic 24-extension field element using + * basic arithmetic. + * + * A cyclotomic element is one raised to the (p^6 - 1)(p^2 + 1)-th power. + * + * @param[out] c - the result. + * @param[in] a - the cyclotomic extension element to square. + */ +void fp24_sqr_cyc_basic(fp24_t c, fp24_t a); + +/** + * Computes the square of a cyclotomic 24-extension field element using + * lazy reduction. + * + * A cyclotomic element is one raised to the (p^6 - 1)(p^2 + 1)-th power. + * + * @param[out] c - the result. + * @param[in] a - the cyclotomic extension element to square. + */ +void fp24_sqr_cyc_lazyr(fp24_t c, fp24_t a); + +/** + * Computes the square of a compressed cyclotomic extension field element. + * + * A cyclotomic element is one raised to the (p^6 - 1)(p^2 + 1)-th power. + * + * @param[out] c - the result. + * @param[in] a - the cyclotomic extension element to square. + */ +void fp24_sqr_pck_basic(fp24_t c, fp24_t a); + +/** + * Computes the square of a compressed cyclotomic extension field element using + * lazy reduction. + * + * A cyclotomic element is one raised to the (p^6 - 1)(p^2 + 1)-th power. + * + * @param[out] c - the result. + * @param[in] a - the cyclotomic extension element to square. + */ +void fp24_sqr_pck_lazyr(fp24_t c, fp24_t a); + +/** + * Tests if a 24-extension field element belongs to the cyclotomic + * subgroup. + * + * @param[in] a - the 24-extension field element to test. + * @return 1 if the extension field element is in the subgroup, 0 otherwise. + */ +int fp24_test_cyc(fp24_t a); + +/** + * Converts a 24-extension field element to a cyclotomic element. + * Computes c = a^(p^6 - 1)*(p^2 + 1). + * + * @param[out] c - the result. + * @param[in] a - a 24-extension field element. + */ +void fp24_conv_cyc(fp24_t c, fp24_t a); + +/** + * Decompresses a compressed cyclotomic extension field element. + * + * @param[out] c - the result. + * @param[in] a - the 24-extension field element to decompress. + */ +void fp24_back_cyc(fp24_t c, fp24_t a); + +/** + * Decompresses multiple compressed cyclotomic extension field elements. + * + * @param[out] c - the result. + * @param[in] a - the 24 field elements to decompress. + * @param[in] n - the number of field elements to decompress. + */ +void fp24_back_cyc_sim(fp24_t *c, fp24_t *a, int n); + /** * Inverts a 24-degree extension field element. Computes c = 1/a. * @@ -3751,6 +3892,16 @@ void fp24_sqr_lazyr(fp24_t c, fp24_t a); */ void fp24_inv(fp24_t c, fp24_t a); +/** + * Computes the inverse of a cyclotomic octdecic extension field element. + * For unitary elements, this is equivalent to computing the conjugate. + * A unitary element is one previously raised to the (p^12 - 1)-th power. + * + * @param[out] c - the result. + * @param[in] a - the 24-degree extension field element to invert. + */ +void fp24_inv_cyc(fp24_t c, fp24_t a); + /** * Computes the Frobenius endomorphism of a 24-degree extension element. * Computes c = a^p. @@ -3771,6 +3922,64 @@ void fp24_frb(fp24_t c, fp24_t a, int i); */ void fp24_exp(fp24_t c, fp24_t a, bn_t b); +/** + * Computes a power of a 24-extension field element by a small exponent. + * Faster formulas are used if the extension field element is cyclotomic. + * + * @param[out] c - the result. + * @param[in] a - the basis. + * @param[in] b - the exponent. + */ +void fp24_exp_dig(fp24_t c, fp24_t a, dig_t b); + +/** + * Computes a power of a cyclotomic 24-extension field element. + * + * @param[out] c - the result. + * @param[in] a - the basis. + * @param[in] b - the exponent. + */ +void fp24_exp_cyc(fp24_t c, fp24_t a, bn_t b); + +/** + * Computes a power of a cyclotomic dodecic extension field element. + * + * @param[out] e - the result. + * @param[in] a - the first element to exponentiate. + * @param[in] b - the first exponent. + * @param[in] c - the second element to exponentiate. + * @param[in] d - the second exponent. + */ +void fp24_exp_cyc_sim(fp24_t e, fp24_t a, bn_t b, fp24_t c, bn_t d); + +/** + * Computes a power of a cyclotomic 24-extension field element. + * + * @param[out] c - the result. + * @param[in] a - the basis. + * @param[in] b - the exponent in sparse form. + * @param[in] l - the length of the exponent in sparse form. + * @param[in] s - the sign of the exponent. + */ +void fp24_exp_cyc_sps(fp24_t c, fp24_t a, const int *b, int l, int s); + +/** + * Compresses a 24-extension field element. + * + * @param[out] c - the result. + * @param[in] a - the 24-extension field element to compress. + */ +void fp24_pck(fp24_t c, fp24_t a); + +/** + * Decompresses a 24-extension field element. + * + * @param[out] c - the result. + * @param[in] a - the 24-extension field element to decompress. + * @return if the decompression was successful + */ +int fp24_upk(fp24_t c, fp24_t a); + /** * Copies the second argument to the first argument. * @@ -4055,15 +4264,6 @@ void fp48_inv(fp48_t c, fp48_t a); */ void fp48_inv_cyc(fp48_t c, fp48_t a); -/** - * Converts a 48-extension field element to a cyclotomic element. Computes - * c = a^(p^6 - 1). - * - * @param[out] c - the result. - * @param[in] a - the 48-extension field element. - */ -void fp48_conv_cyc(fp48_t c, fp48_t a); - /** * Computes the Frobenius endomorphism of a 48-extension element. * Computes c = a^p. @@ -4415,15 +4615,6 @@ void fp54_inv(fp54_t c, fp54_t a); */ void fp54_inv_cyc(fp54_t c, fp54_t a); -/** - * Converts a 54-extension field element to a cyclotomic element. Computes - * c = a^(p^6 - 1). - * - * @param[out] c - the result. - * @param[in] a - the 54-extension field element. - */ -void fp54_conv_cyc(fp54_t c, fp54_t a); - /** * Computes the Frobenius endomorphism of a 54-extension element. * Computes c = a^p. diff --git a/contrib/relic/include/relic_label.h b/contrib/relic/include/relic_label.h index 7b1822876..18d88c5fa 100644 --- a/contrib/relic/include/relic_label.h +++ b/contrib/relic/include/relic_label.h @@ -81,6 +81,7 @@ #undef bench_after #undef bench_compute #undef bench_print +#undef bench_total #define bench_init RLC_PREFIX(bench_init) #define bench_clean RLC_PREFIX(bench_clean) @@ -90,6 +91,7 @@ #define bench_after RLC_PREFIX(bench_after) #define bench_compute RLC_PREFIX(bench_compute) #define bench_print RLC_PREFIX(bench_print) +#define bench_total RLC_PREFIX(bench_total) #undef err_simple_msg #undef err_full_msg @@ -105,12 +107,14 @@ #undef rand_clean #undef rand_seed #undef rand_seed +#undef rand_check #undef rand_bytes #define rand_init RLC_PREFIX(rand_init) #define rand_clean RLC_PREFIX(rand_clean) #define rand_seed RLC_PREFIX(rand_seed) #define rand_seed RLC_PREFIX(rand_seed) +#define rand_check RLC_PREFIX(rand_check) #define rand_bytes RLC_PREFIX(rand_bytes) #undef test_fail @@ -174,7 +178,7 @@ #define bn_st RLC_PREFIX(bn_st) #define bn_t RLC_PREFIX(bn_t) -#undef bn_init +#undef bn_make #undef bn_clean #undef bn_grow #undef bn_trim @@ -227,6 +231,7 @@ #undef bn_div_dig #undef bn_div_rem_dig #undef bn_mod_inv +#undef bn_mod_inv_sim #undef bn_mod_2b #undef bn_mod_dig #undef bn_mod_basic @@ -276,8 +281,9 @@ #undef bn_rec_reg #undef bn_rec_jsf #undef bn_rec_glv +#undef bn_rec_frb -#define bn_init RLC_PREFIX(bn_init) +#define bn_make RLC_PREFIX(bn_make) #define bn_clean RLC_PREFIX(bn_clean) #define bn_grow RLC_PREFIX(bn_grow) #define bn_trim RLC_PREFIX(bn_trim) @@ -330,6 +336,7 @@ #define bn_div_dig RLC_PREFIX(bn_div_dig) #define bn_div_rem_dig RLC_PREFIX(bn_div_rem_dig) #define bn_mod_inv RLC_PREFIX(bn_mod_inv) +#define bn_mod_inv_sim RLC_PREFIX(bn_mod_inv_sim) #define bn_mod_2b RLC_PREFIX(bn_mod_2b) #define bn_mod_dig RLC_PREFIX(bn_mod_dig) #define bn_mod_basic RLC_PREFIX(bn_mod_basic) @@ -379,6 +386,7 @@ #define bn_rec_reg RLC_PREFIX(bn_rec_reg) #define bn_rec_jsf RLC_PREFIX(bn_rec_jsf) #define bn_rec_glv RLC_PREFIX(bn_rec_glv) +#define bn_rec_frb RLC_PREFIX(bn_rec_frb) #undef bn_add1_low #undef bn_addn_low @@ -390,8 +398,10 @@ #undef bn_lshb_low #undef bn_rsh1_low #undef bn_rshb_low +#undef bn_rshs_low #undef bn_mula_low #undef bn_mul1_low +#undef bn_muls_low #undef bn_muln_low #undef bn_muld_low #undef bn_sqra_low @@ -410,8 +420,10 @@ #define bn_lshb_low RLC_PREFIX(bn_lshb_low) #define bn_rsh1_low RLC_PREFIX(bn_rsh1_low) #define bn_rshb_low RLC_PREFIX(bn_rshb_low) +#define bn_rshs_low RLC_PREFIX(bn_rshs_low) #define bn_mula_low RLC_PREFIX(bn_mula_low) #define bn_mul1_low RLC_PREFIX(bn_mul1_low) +#define bn_muls_low RLC_PREFIX(bn_muls_low) #define bn_muln_low RLC_PREFIX(bn_muln_low) #define bn_muld_low RLC_PREFIX(bn_muld_low) #define bn_sqra_low RLC_PREFIX(bn_sqra_low) @@ -502,8 +514,14 @@ #undef fp_inv_monty #undef fp_inv_exgcd #undef fp_inv_divst +#undef fp_inv_jmpds #undef fp_inv_lower #undef fp_inv_sim +#undef fp_smb_basic +#undef fp_smb_binar +#undef fp_smb_divst +#undef fp_smb_jmpds +#undef fp_smb_lower #undef fp_exp_basic #undef fp_exp_slide #undef fp_exp_monty @@ -586,8 +604,14 @@ #define fp_inv_monty RLC_PREFIX(fp_inv_monty) #define fp_inv_exgcd RLC_PREFIX(fp_inv_exgcd) #define fp_inv_divst RLC_PREFIX(fp_inv_divst) +#define fp_inv_jmpds RLC_PREFIX(fp_inv_jmpds) #define fp_inv_lower RLC_PREFIX(fp_inv_lower) #define fp_inv_sim RLC_PREFIX(fp_inv_sim) +#define fp_smb_basic RLC_PREFIX(fp_smb_basic) +#define fp_smb_binar RLC_PREFIX(fp_smb_binar) +#define fp_smb_divst RLC_PREFIX(fp_smb_divst) +#define fp_smb_jmpds RLC_PREFIX(fp_smb_jmpds) +#define fp_smb_lower RLC_PREFIX(fp_smb_lower) #define fp_exp_basic RLC_PREFIX(fp_exp_basic) #define fp_exp_slide RLC_PREFIX(fp_exp_slide) #define fp_exp_monty RLC_PREFIX(fp_exp_monty) @@ -621,6 +645,7 @@ #undef fp_rdcs_low #undef fp_rdcn_low #undef fp_invm_low +#undef fp_smbm_low #define fp_add1_low RLC_PREFIX(fp_add1_low) #define fp_addn_low RLC_PREFIX(fp_addn_low) @@ -650,6 +675,7 @@ #define fp_rdcs_low RLC_PREFIX(fp_rdcs_low) #define fp_rdcn_low RLC_PREFIX(fp_rdcn_low) #define fp_invm_low RLC_PREFIX(fp_invm_low) +#define fp_smbm_low RLC_PREFIX(fp_smbm_low) #undef fp_st #undef fp_t @@ -908,6 +934,7 @@ #undef ep_dbl_slp_basic #undef ep_dbl_projc #undef ep_dbl_jacob +#undef ep_psi #undef ep_mul_basic #undef ep_mul_slide #undef ep_mul_monty @@ -936,13 +963,12 @@ #undef ep_mul_sim_dig #undef ep_norm #undef ep_norm_sim +#undef ep_map_from_field #undef ep_map #undef ep_map_dst -#undef ep_map_dst #undef ep_pck #undef ep_upk - multiplication function, #define ep_mul_basic RLC_PREFIX(ep_mul_basic) #define ep_curve_init RLC_PREFIX(ep_curve_init) #define ep_curve_clean RLC_PREFIX(ep_curve_clean) #define ep_curve_get_a RLC_PREFIX(ep_curve_get_a) @@ -1002,6 +1028,7 @@ #define ep_dbl_slp_basic RLC_PREFIX(ep_dbl_slp_basic) #define ep_dbl_projc RLC_PREFIX(ep_dbl_projc) #define ep_dbl_jacob RLC_PREFIX(ep_dbl_jacob) +#define ep_psi RLC_PREFIX(ep_psi) #define ep_mul_basic RLC_PREFIX(ep_mul_basic) #define ep_mul_slide RLC_PREFIX(ep_mul_slide) #define ep_mul_monty RLC_PREFIX(ep_mul_monty) @@ -1030,9 +1057,9 @@ #define ep_mul_sim_dig RLC_PREFIX(ep_mul_sim_dig) #define ep_norm RLC_PREFIX(ep_norm) #define ep_norm_sim RLC_PREFIX(ep_norm_sim) +#define ep_map_from_field RLC_PREFIX(ep_map_from_field) #define ep_map RLC_PREFIX(ep_map) #define ep_map_dst RLC_PREFIX(ep_map_dst) -#define ep_map_dst RLC_PREFIX(ep_map_dst) #define ep_pck RLC_PREFIX(ep_pck) #define ep_upk RLC_PREFIX(ep_upk) @@ -1223,8 +1250,7 @@ #undef eb_dbl_basic #undef eb_dbl_projc #undef eb_hlv -#undef eb_frb_basic -#undef eb_frb_projc +#undef eb_frb #undef eb_mul_basic #undef eb_mul_lodah #undef eb_mul_lwnaf @@ -1296,8 +1322,7 @@ #define eb_dbl_basic RLC_PREFIX(eb_dbl_basic) #define eb_dbl_projc RLC_PREFIX(eb_dbl_projc) #define eb_hlv RLC_PREFIX(eb_hlv) -#define eb_frb_basic RLC_PREFIX(eb_frb_basic) -#define eb_frb_projc RLC_PREFIX(eb_frb_projc) +#define eb_frb RLC_PREFIX(eb_frb) #define eb_mul_basic RLC_PREFIX(eb_mul_basic) #define eb_mul_lodah RLC_PREFIX(eb_mul_lodah) #define eb_mul_lwnaf RLC_PREFIX(eb_mul_lwnaf) @@ -1366,7 +1391,7 @@ #undef ep2_add_basic #undef ep2_add_slp_basic #undef ep2_add_projc - #undef ep2_sub +#undef ep2_sub #undef ep2_dbl_basic #undef ep2_dbl_slp_basic #undef ep2_dbl_projc @@ -1399,6 +1424,7 @@ #undef ep2_mul_sim_dig #undef ep2_norm #undef ep2_norm_sim +#undef ep2_map_from_field #undef ep2_map #undef ep2_map_dst #undef ep2_frb @@ -1438,7 +1464,7 @@ #define ep2_add_basic RLC_PREFIX(ep2_add_basic) #define ep2_add_slp_basic RLC_PREFIX(ep2_add_slp_basic) #define ep2_add_projc RLC_PREFIX(ep2_add_projc) - #define ep2_sub RLC_PREFIX(ep2_sub) +#define ep2_sub RLC_PREFIX(ep2_sub) #define ep2_dbl_basic RLC_PREFIX(ep2_dbl_basic) #define ep2_dbl_slp_basic RLC_PREFIX(ep2_dbl_slp_basic) #define ep2_dbl_projc RLC_PREFIX(ep2_dbl_projc) @@ -1471,6 +1497,7 @@ #define ep2_mul_sim_dig RLC_PREFIX(ep2_mul_sim_dig) #define ep2_norm RLC_PREFIX(ep2_norm) #define ep2_norm_sim RLC_PREFIX(ep2_norm_sim) +#define ep2_map_from_field RLC_PREFIX(ep2_map_from_field) #define ep2_map RLC_PREFIX(ep2_map) #define ep2_map_dst RLC_PREFIX(ep2_map_dst) #define ep2_frb RLC_PREFIX(ep2_frb) @@ -1766,6 +1793,7 @@ #define fp3_sqrm_low RLC_PREFIX(fp3_sqrm_low) #define fp3_rdcn_low RLC_PREFIX(fp3_rdcn_low) +#undef fp4_field_init #undef fp4_copy #undef fp4_zero #undef fp4_is_zero @@ -1785,15 +1813,19 @@ #undef fp4_mul_basic #undef fp4_mul_lazyr #undef fp4_mul_art +#undef fp4_mul_frb #undef fp4_mul_dxs #undef fp4_sqr_unr #undef fp4_sqr_basic #undef fp4_sqr_lazyr #undef fp4_inv +#undef fp4_inv_sim #undef fp4_inv_cyc #undef fp4_exp #undef fp4_frb +#undef fp4_srt +#define fp4_field_init RLC_PREFIX(fp4_field_init) #define fp4_copy RLC_PREFIX(fp4_copy) #define fp4_zero RLC_PREFIX(fp4_zero) #define fp4_is_zero RLC_PREFIX(fp4_is_zero) @@ -1813,14 +1845,17 @@ #define fp4_mul_basic RLC_PREFIX(fp4_mul_basic) #define fp4_mul_lazyr RLC_PREFIX(fp4_mul_lazyr) #define fp4_mul_art RLC_PREFIX(fp4_mul_art) +#define fp4_mul_frb RLC_PREFIX(fp4_mul_frb) #define fp4_mul_dxs RLC_PREFIX(fp4_mul_dxs) #define fp4_sqr_unr RLC_PREFIX(fp4_sqr_unr) #define fp4_sqr_basic RLC_PREFIX(fp4_sqr_basic) #define fp4_sqr_lazyr RLC_PREFIX(fp4_sqr_lazyr) #define fp4_inv RLC_PREFIX(fp4_inv) +#define fp4_inv_sim RLC_PREFIX(fp4_inv_sim) #define fp4_inv_cyc RLC_PREFIX(fp4_inv_cyc) #define fp4_exp RLC_PREFIX(fp4_exp) #define fp4_frb RLC_PREFIX(fp4_frb) +#define fp4_srt RLC_PREFIX(fp4_srt) #undef fp6_copy #undef fp6_zero @@ -2171,9 +2206,24 @@ #undef fp24_sqr_unr #undef fp24_sqr_basic #undef fp24_sqr_lazyr +#undef fp24_sqr_cyc_basic +#undef fp24_sqr_cyc_lazyr +#undef fp24_sqr_pck_basic +#undef fp24_sqr_pck_lazyr +#undef fp24_test_cyc +#undef fp24_conv_cyc +#undef fp24_back_cyc +#undef fp24_back_cyc_sim #undef fp24_inv +#undef fp24_inv_cyc #undef fp24_frb #undef fp24_exp +#undef fp24_exp_dig +#undef fp24_exp_cyc +#undef fp24_exp_cyc_sim +#undef fp24_exp_cyc_sps +#undef fp24_pck +#undef fp24_upk #define fp24_copy RLC_PREFIX(fp24_copy) #define fp24_zero RLC_PREFIX(fp24_zero) @@ -2198,9 +2248,24 @@ #define fp24_sqr_unr RLC_PREFIX(fp24_sqr_unr) #define fp24_sqr_basic RLC_PREFIX(fp24_sqr_basic) #define fp24_sqr_lazyr RLC_PREFIX(fp24_sqr_lazyr) +#define fp24_sqr_cyc_basic RLC_PREFIX(fp24_sqr_cyc_basic) +#define fp24_sqr_cyc_lazyr RLC_PREFIX(fp24_sqr_cyc_lazyr) +#define fp24_sqr_pck_basic RLC_PREFIX(fp24_sqr_pck_basic) +#define fp24_sqr_pck_lazyr RLC_PREFIX(fp24_sqr_pck_lazyr) +#define fp24_test_cyc RLC_PREFIX(fp24_test_cyc) +#define fp24_conv_cyc RLC_PREFIX(fp24_conv_cyc) +#define fp24_back_cyc RLC_PREFIX(fp24_back_cyc) +#define fp24_back_cyc_sim RLC_PREFIX(fp24_back_cyc_sim) #define fp24_inv RLC_PREFIX(fp24_inv) +#define fp24_inv_cyc RLC_PREFIX(fp24_inv_cyc) #define fp24_frb RLC_PREFIX(fp24_frb) #define fp24_exp RLC_PREFIX(fp24_exp) +#define fp24_exp_dig RLC_PREFIX(fp24_exp_dig) +#define fp24_exp_cyc RLC_PREFIX(fp24_exp_cyc) +#define fp24_exp_cyc_sim RLC_PREFIX(fp24_exp_cyc_sim) +#define fp24_exp_cyc_sps RLC_PREFIX(fp24_exp_cyc_sps) +#define fp24_pck RLC_PREFIX(fp24_pck) +#define fp24_upk RLC_PREFIX(fp24_upk) #undef fp48_copy #undef fp48_zero @@ -2388,6 +2453,8 @@ #undef pp_add_k12_projc_basic #undef pp_add_k12_projc_lazyr #undef pp_add_lit_k12 +#undef pp_add_k24_basic +#undef pp_add_k24_projc #undef pp_add_k48_basic #undef pp_add_k48_projc #undef pp_add_k54_basic @@ -2401,6 +2468,8 @@ #undef pp_dbl_k12_basic #undef pp_dbl_k12_projc_basic #undef pp_dbl_k12_projc_lazyr +#undef pp_dbl_k24_basic +#undef pp_dbl_k24_projc #undef pp_dbl_k48_basic #undef pp_dbl_k48_projc #undef pp_dbl_k54_basic @@ -2409,11 +2478,13 @@ #undef pp_exp_k2 #undef pp_exp_k8 #undef pp_exp_k12 +#undef pp_exp_k24 #undef pp_exp_k48 #undef pp_exp_k54 #undef pp_norm_k2 #undef pp_norm_k8 #undef pp_norm_k12 +#undef pp_norm_k24 #undef pp_map_tatep_k2 #undef pp_map_sim_tatep_k2 #undef pp_map_weilp_k2 @@ -2425,6 +2496,8 @@ #undef pp_map_sim_weilp_k12 #undef pp_map_oatep_k12 #undef pp_map_sim_oatep_k12 +#undef pp_map_k24 +#undef pp_map_sim_k24 #undef pp_map_k48 #undef pp_map_k54 @@ -2440,6 +2513,8 @@ #define pp_add_k12_projc_basic RLC_PREFIX(pp_add_k12_projc_basic) #define pp_add_k12_projc_lazyr RLC_PREFIX(pp_add_k12_projc_lazyr) #define pp_add_lit_k12 RLC_PREFIX(pp_add_lit_k12) +#define pp_add_k24_basic RLC_PREFIX(pp_add_k24_basic) +#define pp_add_k24_projc RLC_PREFIX(pp_add_k24_projc) #define pp_add_k48_basic RLC_PREFIX(pp_add_k48_basic) #define pp_add_k48_projc RLC_PREFIX(pp_add_k48_projc) #define pp_add_k54_basic RLC_PREFIX(pp_add_k54_basic) @@ -2453,6 +2528,8 @@ #define pp_dbl_k12_basic RLC_PREFIX(pp_dbl_k12_basic) #define pp_dbl_k12_projc_basic RLC_PREFIX(pp_dbl_k12_projc_basic) #define pp_dbl_k12_projc_lazyr RLC_PREFIX(pp_dbl_k12_projc_lazyr) +#define pp_dbl_k24_basic RLC_PREFIX(pp_dbl_k24_basic) +#define pp_dbl_k24_projc RLC_PREFIX(pp_dbl_k24_projc) #define pp_dbl_k48_basic RLC_PREFIX(pp_dbl_k48_basic) #define pp_dbl_k48_projc RLC_PREFIX(pp_dbl_k48_projc) #define pp_dbl_k54_basic RLC_PREFIX(pp_dbl_k54_basic) @@ -2461,11 +2538,13 @@ #define pp_exp_k2 RLC_PREFIX(pp_exp_k2) #define pp_exp_k8 RLC_PREFIX(pp_exp_k8) #define pp_exp_k12 RLC_PREFIX(pp_exp_k12) +#define pp_exp_k24 RLC_PREFIX(pp_exp_k24) #define pp_exp_k48 RLC_PREFIX(pp_exp_k48) #define pp_exp_k54 RLC_PREFIX(pp_exp_k54) #define pp_norm_k2 RLC_PREFIX(pp_norm_k2) #define pp_norm_k8 RLC_PREFIX(pp_norm_k8) #define pp_norm_k12 RLC_PREFIX(pp_norm_k12) +#define pp_norm_k24 RLC_PREFIX(pp_norm_k24) #define pp_map_tatep_k2 RLC_PREFIX(pp_map_tatep_k2) #define pp_map_sim_tatep_k2 RLC_PREFIX(pp_map_sim_tatep_k2) #define pp_map_weilp_k2 RLC_PREFIX(pp_map_weilp_k2) @@ -2477,6 +2556,8 @@ #define pp_map_sim_weilp_k12 RLC_PREFIX(pp_map_sim_weilp_k12) #define pp_map_oatep_k12 RLC_PREFIX(pp_map_oatep_k12) #define pp_map_sim_oatep_k12 RLC_PREFIX(pp_map_sim_oatep_k12) +#define pp_map_k24 RLC_PREFIX(pp_map_k24) +#define pp_map_sim_k24 RLC_PREFIX(pp_map_sim_k24) #define pp_map_k48 RLC_PREFIX(pp_map_k48) #define pp_map_k54 RLC_PREFIX(pp_map_k54) @@ -2523,6 +2604,22 @@ #undef cp_ecss_gen #undef cp_ecss_sig #undef cp_ecss_ver +#undef cp_pdpub_gen +#undef cp_pdpub_ask +#undef cp_pdpub_ans +#undef cp_pdpub_ver +#undef cp_pdprv_gen +#undef cp_pdprv_ask +#undef cp_pdprv_ans +#undef cp_pdprv_ver +#undef cp_lvpub_gen +#undef cp_lvpub_ask +#undef cp_lvpub_ans +#undef cp_lvpub_ver +#undef cp_lvprv_gen +#undef cp_lvprv_ask +#undef cp_lvprv_ans +#undef cp_lvprv_ver #undef cp_sokaka_gen #undef cp_sokaka_gen_prv #undef cp_sokaka_key @@ -2574,6 +2671,26 @@ #undef cp_vbnn_gen_prv #undef cp_vbnn_sig #undef cp_vbnn_ver +#undef cp_pokdl_prv +#undef cp_pokdl_ver +#undef cp_pokor_prv +#undef cp_pokor_ver +#undef cp_sokdl_sig +#undef cp_sokdl_ver +#undef cp_sokor_sig +#undef cp_sokor_ver +#undef cp_ers_gen +#undef cp_ers_gen_key +#undef cp_ers_sig +#undef cp_ers_ver +#undef cp_ers_ext +#undef cp_smlers_sig +#undef cp_smlers_ver +#undef cp_smlers_ext +#undef cp_etrs_sig +#undef cp_etrs_ver +#undef cp_etrs_ext +#undef cp_etrs_uni #undef cp_cmlhs_init #undef cp_cmlhs_gen #undef cp_cmlhs_sig @@ -2589,6 +2706,10 @@ #undef cp_mklhs_ver #undef cp_mklhs_off #undef cp_mklhs_onv +#undef cp_lapsi_gen +#undef cp_lapsi_ask +#undef cp_lapsi_ans +#undef cp_lapsi_int #define cp_rsa_gen RLC_PREFIX(cp_rsa_gen) #define cp_rsa_enc RLC_PREFIX(cp_rsa_enc) @@ -2620,6 +2741,22 @@ #define cp_ecss_gen RLC_PREFIX(cp_ecss_gen) #define cp_ecss_sig RLC_PREFIX(cp_ecss_sig) #define cp_ecss_ver RLC_PREFIX(cp_ecss_ver) +#define cp_pdpub_gen RLC_PREFIX(cp_pdpub_gen) +#define cp_pdpub_ask RLC_PREFIX(cp_pdpub_ask) +#define cp_pdpub_ans RLC_PREFIX(cp_pdpub_ans) +#define cp_pdpub_ver RLC_PREFIX(cp_pdpub_ver) +#define cp_pdprv_gen RLC_PREFIX(cp_pdprv_gen) +#define cp_pdprv_ask RLC_PREFIX(cp_pdprv_ask) +#define cp_pdprv_ans RLC_PREFIX(cp_pdprv_ans) +#define cp_pdprv_ver RLC_PREFIX(cp_pdprv_ver) +#define cp_lvpub_gen RLC_PREFIX(cp_lvpub_gen) +#define cp_lvpub_ask RLC_PREFIX(cp_lvpub_ask) +#define cp_lvpub_ans RLC_PREFIX(cp_lvpub_ans) +#define cp_lvpub_ver RLC_PREFIX(cp_lvpub_ver) +#define cp_lvprv_gen RLC_PREFIX(cp_lvprv_gen) +#define cp_lvprv_ask RLC_PREFIX(cp_lvprv_ask) +#define cp_lvprv_ans RLC_PREFIX(cp_lvprv_ans) +#define cp_lvprv_ver RLC_PREFIX(cp_lvprv_ver) #define cp_sokaka_gen RLC_PREFIX(cp_sokaka_gen) #define cp_sokaka_gen_prv RLC_PREFIX(cp_sokaka_gen_prv) #define cp_sokaka_key RLC_PREFIX(cp_sokaka_key) @@ -2671,6 +2808,26 @@ #define cp_vbnn_gen_prv RLC_PREFIX(cp_vbnn_gen_prv) #define cp_vbnn_sig RLC_PREFIX(cp_vbnn_sig) #define cp_vbnn_ver RLC_PREFIX(cp_vbnn_ver) +#define cp_pokdl_prv RLC_PREFIX(cp_pokdl_prv) +#define cp_pokdl_ver RLC_PREFIX(cp_pokdl_ver) +#define cp_pokor_prv RLC_PREFIX(cp_pokor_prv) +#define cp_pokor_ver RLC_PREFIX(cp_pokor_ver) +#define cp_sokdl_sig RLC_PREFIX(cp_sokdl_sig) +#define cp_sokdl_ver RLC_PREFIX(cp_sokdl_ver) +#define cp_sokor_sig RLC_PREFIX(cp_sokor_sig) +#define cp_sokor_ver RLC_PREFIX(cp_sokor_ver) +#define cp_ers_gen RLC_PREFIX(cp_ers_gen) +#define cp_ers_gen_key RLC_PREFIX(cp_ers_gen_key) +#define cp_ers_sig RLC_PREFIX(cp_ers_sig) +#define cp_ers_ver RLC_PREFIX(cp_ers_ver) +#define cp_ers_ext RLC_PREFIX(cp_ers_ext) +#define cp_smlers_sig RLC_PREFIX(cp_smlers_sig) +#define cp_smlers_ver RLC_PREFIX(cp_smlers_ver) +#define cp_smlers_ext RLC_PREFIX(cp_smlers_ext) +#define cp_etrs_sig RLC_PREFIX(cp_etrs_sig) +#define cp_etrs_ver RLC_PREFIX(cp_etrs_ver) +#define cp_etrs_ext RLC_PREFIX(cp_etrs_ext) +#define cp_etrs_uni RLC_PREFIX(cp_etrs_uni) #define cp_cmlhs_init RLC_PREFIX(cp_cmlhs_init) #define cp_cmlhs_gen RLC_PREFIX(cp_cmlhs_gen) #define cp_cmlhs_sig RLC_PREFIX(cp_cmlhs_sig) @@ -2686,6 +2843,10 @@ #define cp_mklhs_ver RLC_PREFIX(cp_mklhs_ver) #define cp_mklhs_off RLC_PREFIX(cp_mklhs_off) #define cp_mklhs_onv RLC_PREFIX(cp_mklhs_onv) +#define cp_lapsi_gen RLC_PREFIX(cp_lapsi_gen) +#define cp_lapsi_ask RLC_PREFIX(cp_lapsi_ask) +#define cp_lapsi_ans RLC_PREFIX(cp_lapsi_ans) +#define cp_lapsi_int RLC_PREFIX(cp_lapsi_int) #undef md_map_sh224 #undef md_map_sh256 diff --git a/contrib/relic/include/relic_md.h b/contrib/relic/include/relic_md.h index 1a16b8423..a624b66cc 100644 --- a/contrib/relic/include/relic_md.h +++ b/contrib/relic/include/relic_md.h @@ -96,9 +96,9 @@ enum { #define md_map(H, M, L) md_map_sh384(H, M, L) #elif MD_MAP == SH512 #define md_map(H, M, L) md_map_sh512(H, M, L) -#elif MD_MAP == BLAKE2S_160 +#elif MD_MAP == B2S160 #define md_map(H, M, L) md_map_b2s160(H, M, L) -#elif MD_MAP == BLAKE2S_256 +#elif MD_MAP == B2S256 #define md_map(H, M, L) md_map_b2s256(H, M, L) #endif diff --git a/contrib/relic/include/relic_pc.h b/contrib/relic/include/relic_pc.h index aa7198964..5c55b1055 100644 --- a/contrib/relic/include/relic_pc.h +++ b/contrib/relic/include/relic_pc.h @@ -54,12 +54,26 @@ */ /** @{ */ #if FP_PRIME < 1536 + #define RLC_G1_LOWER ep_ #define RLC_G1_UPPER EP + +#if FP_PRIME == 509 +#define RLC_G2_LOWER ep4_ +#else #define RLC_G2_LOWER ep2_ +#endif + #define RLC_G2_UPPER EP + +#if FP_PRIME == 509 +#define RLC_GT_LOWER fp24_ +#else #define RLC_GT_LOWER fp12_ +#endif + #define RLC_PC_LOWER pp_ + #else #define RLC_G1_LOWER ep_ #define RLC_G1_UPPER EP @@ -246,7 +260,23 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; #define pc_param_level() RLC_CAT(RLC_G1_LOWER, param_level)() /** - * Tests if a G_1 element is the unity. + * Tests if a G_1 element is on the curve. + * + * @param[in] P - the element to test. + * @return 1 if the element it the unity, 0 otherwise. + */ +#define g1_on_curve(P) RLC_CAT(RLC_G1_LOWER, on_curve)(P) + +/** + * Tests if a G_2 element is on the curve. + * + * @param[in] P - the element to test. + * @return 1 if the element it the unity, 0 otherwise. + */ +#define g2_on_curve(P) RLC_CAT(RLC_G2_LOWER, on_curve)(P) + +/** + * Tests if a G_1 element is the point at infinity. * * @param[in] P - the element to test. * @return 1 if the element it the unity, 0 otherwise. @@ -254,7 +284,7 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; #define g1_is_infty(P) RLC_CAT(RLC_G1_LOWER, is_infty)(P) /** - * Tests if a G_2 element is the unity. + * Tests if a G_2 element is the point at infinity. * * @param[in] P - the element to test. * @return 1 if the element it the unity, 0 otherwise. @@ -262,7 +292,7 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; #define g2_is_infty(P) RLC_CAT(RLC_G2_LOWER, is_infty)(P) /** - * Tests if a G_T element is the unity. + * Tests if a G_T element is the identity. * * @param[in] A - the element to test. * @return 1 if the element it the unity, 0 otherwise. @@ -652,15 +682,6 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; */ #define g2_mul_dig(R, P, K) RLC_CAT(RLC_G2_LOWER, mul_dig)(R, P, K) -/** - * Exponentiates an element from G_T by a small integer. Computes c = a^b. - * - * @param[out] R - the result. - * @param[in] P - the element to multiply. - * @param[in] K - the small integer. - */ -#define gt_exp_dig(C, A, B) RLC_CAT(RLC_GT_LOWER, exp_dig)(C, A, B) - /** * Builds a precomputation table for multiplying an element from G_1. * @@ -781,6 +802,16 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; */ #define g2_mul_sim_gen(R, K, Q, L) RLC_CAT(RLC_G2_LOWER, mul_sim_gen)(R, K, Q, L) +/** + * Exponetiates a G_2 element using the i-th power Frobenius. + * Computes C = [p^i]A. + * + * @param[out] C - the result. + * @param[in] A - the element to exponentiate. + * @param[in] I - the power of the Frobenius map. + */ +#define g2_frb(C, A, I) RLC_CAT(RLC_G2_LOWER, frb)(C, A, I) + /** * Exponetiates a G_T element using the i-th power Frobenius. * Computes C = A^(p^i). @@ -818,9 +849,17 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; * @param[in] Q - the second element. */ #if FP_PRIME < 1536 + +#if FP_PRIME == 509 +#define pc_map(R, P, Q); RLC_CAT(RLC_PC_LOWER, map_k24)(R, P, Q) +#else #define pc_map(R, P, Q); RLC_CAT(RLC_PC_LOWER, map_k12)(R, P, Q) +#endif + #else + #define pc_map(R, P, Q); RLC_CAT(RLC_PC_LOWER, map_k2)(R, P, Q) + #endif /** @@ -833,7 +872,13 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; * @param[in] M - the number of pairing arguments. */ #if FP_PRIME < 1536 + +#if FP_PRIME == 509 +#define pc_map_sim(R, P, Q, M); RLC_CAT(RLC_PC_LOWER, map_sim_k24)(R, P, Q, M) +#else #define pc_map_sim(R, P, Q, M); RLC_CAT(RLC_PC_LOWER, map_sim_k12)(R, P, Q, M) +#endif + #else #define pc_map_sim(R, P, Q, M); RLC_CAT(RLC_PC_LOWER, map_sim_k2)(R, P, Q, M) #endif @@ -845,7 +890,13 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; * @param[in] A - the field element to exponentiate. */ #if FP_PRIME < 1536 + +#if FP_PRIME == 509 +#define pc_exp(C, A); RLC_CAT(RLC_PC_LOWER, exp_k24)(C, A) +#else #define pc_exp(C, A); RLC_CAT(RLC_PC_LOWER, exp_k12)(C, A) +#endif + #else #define pc_exp(C, A); RLC_CAT(RLC_PC_LOWER, exp_k2)(C, A) #endif @@ -920,6 +971,15 @@ void g2_mul_gen(g2_t r, bn_t k); */ void gt_exp(gt_t c, gt_t a, bn_t b); +/** + * Exponentiates an element from G_T by a small integer. Computes c = a^b. + * + * @param[out] c - the result. + * @param[in] a - the element to exponentiate. + * @param[in] b - the integer exponent. + */ +void gt_exp_dig(gt_t c, gt_t a, dig_t b); + /** * Exponentiates two element from G_T by integers simultaneously. Computes * e = a^b * c^d. diff --git a/contrib/relic/include/relic_pp.h b/contrib/relic/include/relic_pp.h index 5d4db85ab..4baee4c32 100644 --- a/contrib/relic/include/relic_pp.h +++ b/contrib/relic/include/relic_pp.h @@ -45,6 +45,22 @@ /* Macro definitions */ /*============================================================================*/ +/** + * Adds two points and evaluates the corresponding line function at another + * point on an elliptic curve with embedding degree 2 using projective + * coordinates. + * + * @param[out] L - the result of the evaluation. + * @param[in, out] R - the resulting point and first point to add. + * @param[in] P - the second point to add. + * @param[in] Q - the affine point to evaluate the line function. + */ +#if PP_EXT == BASIC +#define pp_add_k2_projc(L, R, P, Q) pp_add_k2_projc_basic(L, R, P, Q) +#else +#define pp_add_k2_projc(L, R, P, Q) pp_add_k2_projc_lazyr(L, R, P, Q) +#endif + /** * Adds two points and evaluates the corresponding line function at another * point on an elliptic curve with embedding degree 2. @@ -62,18 +78,18 @@ /** * Adds two points and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 2 using projective + * point on an elliptic curve with embedding degree 8 using projective * coordinates. * * @param[out] L - the result of the evaluation. * @param[in, out] R - the resulting point and first point to add. - * @param[in] P - the second point to add. - * @param[in] Q - the affine point to evaluate the line function. + * @param[in] Q - the second point to add. + * @param[in] P - the affine point to evaluate the line function. */ #if PP_EXT == BASIC -#define pp_add_k2_projc(L, R, P, Q) pp_add_k2_projc_basic(L, R, P, Q) -#else -#define pp_add_k2_projc(L, R, P, Q) pp_add_k2_projc_lazyr(L, R, P, Q) +#define pp_add_k8_projc(L, R, Q, P) pp_add_k8_projc_basic(L, R, Q, P) +#elif PP_EXT == LAZYR +#define pp_add_k8_projc(L, R, Q, P) pp_add_k8_projc_lazyr(L, R, Q, P) #endif /** @@ -93,7 +109,7 @@ /** * Adds two points and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 8 using projective + * point on an elliptic curve with embedding degree 12 using projective * coordinates. * * @param[out] L - the result of the evaluation. @@ -102,9 +118,9 @@ * @param[in] P - the affine point to evaluate the line function. */ #if PP_EXT == BASIC -#define pp_add_k8_projc(L, R, Q, P) pp_add_k8_projc_basic(L, R, Q, P) +#define pp_add_k12_projc(L, R, Q, P) pp_add_k12_projc_basic(L, R, Q, P) #elif PP_EXT == LAZYR -#define pp_add_k8_projc(L, R, Q, P) pp_add_k8_projc_lazyr(L, R, Q, P) +#define pp_add_k12_projc(L, R, Q, P) pp_add_k12_projc_lazyr(L, R, Q, P) #endif /** @@ -124,18 +140,17 @@ /** * Adds two points and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 12 using projective - * coordinates. + * point on an elliptic curve with embedding degree 24. * * @param[out] L - the result of the evaluation. * @param[in, out] R - the resulting point and first point to add. * @param[in] Q - the second point to add. * @param[in] P - the affine point to evaluate the line function. */ -#if PP_EXT == BASIC -#define pp_add_k12_projc(L, R, Q, P) pp_add_k12_projc_basic(L, R, Q, P) -#elif PP_EXT == LAZYR -#define pp_add_k12_projc(L, R, Q, P) pp_add_k12_projc_lazyr(L, R, Q, P) +#if EP_ADD == BASIC +#define pp_add_k24(L, R, Q, P) pp_add_k24_basic(L, R, Q, P) +#else +#define pp_add_k24(L, R, Q, P) pp_add_k24_projc(L, R, Q, P) #endif /** @@ -168,6 +183,22 @@ #define pp_add_k54(L, RX, RY, RZ, QX, QY, P) pp_add_k54_projc(L, RX, RY, RZ, QX, QY, P) #endif +/** + * Doubles a point and evaluates the corresponding line function at another + * point on an elliptic curve with embedding degree 2 using projective + * coordinates. + * + * @param[out] L - the result of the evaluation. + * @param[in, out] R - the resulting point. + * @param[in] Q - the point to double. + * @param[in] P - the affine point to evaluate the line function. + */ +#if PP_EXT == BASIC +#define pp_dbl_k2_projc(L, R, P, Q) pp_dbl_k2_projc_basic(L, R, P, Q) +#elif PP_EXT == LAZYR +#define pp_dbl_k2_projc(L, R, P, Q) pp_dbl_k2_projc_lazyr(L, R, P, Q) +#endif + /** * Doubles a point and evaluates the corresponding line function at another * point on an elliptic curve with embedding degree 2. @@ -185,22 +216,23 @@ /** * Doubles a point and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 8. + * point on an elliptic curve with embedding degree 12 using projective + * coordinates. * * @param[out] L - the result of the evaluation. - * @param[out] R - the resulting point. + * @param[in, out] R - the resulting point. * @param[in] Q - the point to double. * @param[in] P - the affine point to evaluate the line function. */ -#if EP_ADD == BASIC -#define pp_dbl_k8(L, R, Q, P) pp_dbl_k8_basic(L, R, Q, P) -#else -#define pp_dbl_k8(L, R, Q, P) pp_dbl_k8_projc(L, R, Q, P) +#if PP_EXT == BASIC +#define pp_dbl_k8_projc(L, R, Q, P) pp_dbl_k8_projc_basic(L, R, Q, P) +#elif PP_EXT == LAZYR +#define pp_dbl_k8_projc(L, R, Q, P) pp_dbl_k8_projc_lazyr(L, R, Q, P) #endif /** * Doubles a point and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 12. + * point on an elliptic curve with embedding degree 8. * * @param[out] L - the result of the evaluation. * @param[out] R - the resulting point. @@ -208,9 +240,9 @@ * @param[in] P - the affine point to evaluate the line function. */ #if EP_ADD == BASIC -#define pp_dbl_k12(L, R, Q, P) pp_dbl_k12_basic(L, R, Q, P) +#define pp_dbl_k8(L, R, Q, P) pp_dbl_k8_basic(L, R, Q, P) #else -#define pp_dbl_k12(L, R, Q, P) pp_dbl_k12_projc(L, R, Q, P) +#define pp_dbl_k8(L, R, Q, P) pp_dbl_k8_projc(L, R, Q, P) #endif /** @@ -224,41 +256,39 @@ * @param[in] P - the affine point to evaluate the line function. */ #if PP_EXT == BASIC -#define pp_dbl_k8_projc(L, R, Q, P) pp_dbl_k8_projc_basic(L, R, Q, P) +#define pp_dbl_k12_projc(L, R, Q, P) pp_dbl_k12_projc_basic(L, R, Q, P) #elif PP_EXT == LAZYR -#define pp_dbl_k8_projc(L, R, Q, P) pp_dbl_k8_projc_lazyr(L, R, Q, P) +#define pp_dbl_k12_projc(L, R, Q, P) pp_dbl_k12_projc_lazyr(L, R, Q, P) #endif /** * Doubles a point and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 2 using projective - * coordinates. + * point on an elliptic curve with embedding degree 12. * * @param[out] L - the result of the evaluation. - * @param[in, out] R - the resulting point. + * @param[out] R - the resulting point. * @param[in] Q - the point to double. * @param[in] P - the affine point to evaluate the line function. */ -#if PP_EXT == BASIC -#define pp_dbl_k2_projc(L, R, P, Q) pp_dbl_k2_projc_basic(L, R, P, Q) -#elif PP_EXT == LAZYR -#define pp_dbl_k2_projc(L, R, P, Q) pp_dbl_k2_projc_lazyr(L, R, P, Q) +#if EP_ADD == BASIC +#define pp_dbl_k12(L, R, Q, P) pp_dbl_k12_basic(L, R, Q, P) +#else +#define pp_dbl_k12(L, R, Q, P) pp_dbl_k12_projc(L, R, Q, P) #endif /** * Doubles a point and evaluates the corresponding line function at another - * point on an elliptic curve with embedding degree 12 using projective - * coordinates. + * point on an elliptic curve with embedding degree 24. * * @param[out] L - the result of the evaluation. - * @param[in, out] R - the resulting point. + * @param[out] R - the resulting point. * @param[in] Q - the point to double. * @param[in] P - the affine point to evaluate the line function. */ -#if PP_EXT == BASIC -#define pp_dbl_k12_projc(L, R, Q, P) pp_dbl_k12_projc_basic(L, R, Q, P) -#elif PP_EXT == LAZYR -#define pp_dbl_k12_projc(L, R, Q, P) pp_dbl_k12_projc_lazyr(L, R, Q, P) +#if EP_ADD == BASIC +#define pp_dbl_k24(L, R, Q, P) pp_dbl_k24_basic(L, R, Q, P) +#else +#define pp_dbl_k24(L, R, Q, P) pp_dbl_k24_projc(L, R, Q, P) #endif /** @@ -487,6 +517,29 @@ void pp_add_k12_projc_lazyr(fp12_t l, ep2_t r, ep2_t q, ep_t p); */ void pp_add_lit_k12(fp12_t l, ep_t r, ep_t p, ep2_t q); +/** + * Adds two points and evaluates the corresponding line function at another + * point on an elliptic curve with embedding degree 24 using affine coordinates. + * + * @param[out] l - the result of the evaluation. + * @param[in, out] r - the resulting point and first point to add. + * @param[in] q - the second point to add. + * @param[in] p - the affine point to evaluate the line function. + */ +void pp_add_k24_basic(fp24_t l, ep4_t r, ep4_t q, ep_t p); + +/** + * Adds two points and evaluates the corresponding line function at another + * point on an elliptic curve with embedding degree 24 using projective + * coordinates. + * + * @param[out] l - the result of the evaluation. + * @param[in, out] r - the resulting point and first point to add. + * @param[in] q - the second point to add. + * @param[in] p - the affine point to evaluate the line function. + */ +void pp_add_k24_projc(fp24_t l, ep4_t r, ep4_t q, ep_t p); + /** * Adds two points and evaluates the corresponding line function at another * point on an elliptic curve with embedding degree 48 using affine coordinates. @@ -641,6 +694,30 @@ void pp_dbl_k12_projc_basic(fp12_t l, ep2_t r, ep2_t q, ep_t p); */ void pp_dbl_k12_projc_lazyr(fp12_t l, ep2_t r, ep2_t q, ep_t p); +/** + * Doubles a point and evaluates the corresponding line function at another + * point on an elliptic curve with embedding degree 24 using affine + * coordinates. + * + * @param[out] l - the result of the evaluation. + * @param[in, out] r - the resulting point. + * @param[in] q - the point to double. + * @param[in] p - the affine point to evaluate the line function. + */ +void pp_dbl_k24_basic(fp24_t l, ep4_t r, ep4_t q, ep_t p); + +/** + * Doubles a point and evaluates the corresponding line function at another + * point on an elliptic curve with embedding degree 24 using projective + * coordinates. + * + * @param[out] l - the result of the evaluation. + * @param[in, out] r - the resulting point. + * @param[in] q - the point to double. + * @param[in] p - the affine point to evaluate the line function. + */ +void pp_dbl_k24_projc(fp24_t l, ep4_t r, ep4_t q, ep_t p); + /** * Doubles a point and evaluates the corresponding line function at another * point on an elliptic curve with embedding degree 48 using affine @@ -728,6 +805,15 @@ void pp_exp_k8(fp8_t c, fp8_t a); */ void pp_exp_k12(fp12_t c, fp12_t a); +/** + * Computes the final exponentiation for a pairing defined over curves of + * embedding degree 24. Computes c = a^(p^24 - 1)/r. + * + * @param[out] c - the result. + * @param[in] a - the extension field element to exponentiate. + */ +void pp_exp_k24(fp24_t c, fp24_t a); + /** * Computes the final exponentiation for a pairing defined over curves of * embedding degree 48. Computes c = a^(p^48 - 1)/r. @@ -773,6 +859,15 @@ void pp_norm_k8(ep2_t c, ep2_t a); */ void pp_norm_k12(ep2_t c, ep2_t a); +/** + * Normalizes the accumulator point used inside pairing computation defined + * over curves of embedding degree 24. + * + * @param[out] r - the resulting point. + * @param[in] p - the point to normalize. + */ +void pp_norm_k24(ep4_t c, ep4_t a); + /** * Computes the Tate pairing of two points in a parameterized elliptic curve * with embedding degree 12. @@ -888,6 +983,27 @@ void pp_map_oatep_k12(fp12_t r, ep_t p, ep2_t q); */ void pp_map_sim_oatep_k12(fp12_t r, ep_t *p, ep2_t *q, int m); +/** + * Computes the Optimal Ate pairing of two points in a parameterized elliptic + * curve with embedding degree 24. + * + * @param[out] r - the result. + * @param[in] q - the first elliptic curve point. + * @param[in] p - the second elliptic curve point. + */ +void pp_map_k24(fp24_t r, ep_t p, ep4_t q); + +/** + * Computes the optimal ate multi-pairing of in a parameterized elliptic + * curve with embedding degree 24. + * + * @param[out] r - the result. + * @param[in] q - the first pairing arguments. + * @param[in] p - the second pairing arguments. + * @param[in] m - the number of pairings to evaluate. + */ +void pp_map_sim_k24(fp24_t r, ep_t *p, ep4_t *q, int m); + /** * Computes the Optimal Ate pairing of two points in a parameterized elliptic * curve with embedding degree 48. diff --git a/contrib/relic/include/relic_rand.h b/contrib/relic/include/relic_rand.h index 320507fb0..bf92ac376 100644 --- a/contrib/relic/include/relic_rand.h +++ b/contrib/relic/include/relic_rand.h @@ -47,7 +47,7 @@ */ #if RAND == HASHD -#if MD_MAP == SH224 || MD_MAP == SH256 || MD_MAP == BLAKE2S_160 || MD_MAP == BLAKE2S_256 +#if MD_MAP == SH224 || MD_MAP == SH256 || MD_MAP == B2S160 || MD_MAP == B2S256 #define RLC_RAND_SIZE (1 + 2*440/8) #elif MD_MAP == SH384 || MD_MAP == SH512 #define RLC_RAND_SIZE (1 + 2*888/8) @@ -104,6 +104,16 @@ void rand_seed(void (*callback)(uint8_t *, int, void *), void *arg); #endif +/** + * Performs a basic self-test in the pseudo-random number generator output, and + * raises an exception in case a string of identifical bytes is found. + * + * @param[out] buf - the buffer to check. + * @param[in] size - the number of bytes to check. + * @throw ERR_NO_RAND - if the pseudo-random number generator is stuck. + */ +int rand_check(uint8_t *buf, int size); + /** * Gathers pseudo-random bytes from the pseudo-random number generator. * diff --git a/contrib/relic/include/relic_types.h b/contrib/relic/include/relic_types.h index 5e38a69e8..92316bfec 100644 --- a/contrib/relic/include/relic_types.h +++ b/contrib/relic/include/relic_types.h @@ -40,6 +40,10 @@ #include #endif +#if defined(_MSC_VER) && WSIZE == 64 +#include +#endif + /*============================================================================*/ /* Constant definitions */ /*============================================================================*/ @@ -109,12 +113,48 @@ typedef uint32_t dbl_t; #elif WSIZE == 32 typedef uint64_t dbl_t; #elif WSIZE == 64 -#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#ifdef _MSC_VER +/** MSVS does not support 128-bit type. */ +#define RLC_CONF_NODBL +#else typedef __uint128_t dbl_t; -#elif ARITH == EASY -#error "Easy backend in 64-bit mode supported only in GCC compiler." +#endif +#endif + +/** + * Multiplies two digits to give a double precision result. + * + * @param[out] H - the higher half of the result. + * @param[out] L - the lower half of the result. + * @param[in] A - the first digit to multiply. + * @param[in] B - the second digit to multiply. + */ +#ifdef RLC_CONF_NODBL +#define RLC_MUL_DIG(H, L, A, B) L = _umul128(A, B, &(H)) #else +#define RLC_MUL_DIG(H, L, A, B) \ + H = ((dbl_t)(A) * (dbl_t)(B)) >> RLC_DIG; \ + L = (A) * (B); \ + #endif + +/** + * Divides a double-digit by a digit, setting quotient and remainder. + * + * @param[out] Q - the quotient. + * @param[out] R - the remainder. + * @param[in] H - the higher half of the dividend. + * @param[in] L - the lower half of the dividend. + * @param[in] D - the divisor. + */ +#ifdef RLC_CONF_NODBL +#define RLC_DIV_DIG(Q, R, H, L, D) Q = _udiv128(H, L, D, &(R)) +#else + +#define RLC_DIV_DIG(Q, R, H, L, D) \ + Q = (((dbl_t)(H) << RLC_DIG) | (L)) / (D); \ + R = (((dbl_t)(H) << RLC_DIG) | (L)) - (dbl_t)(Q) * (dbl_t)(D); \ + #endif /* diff --git a/contrib/relic/include/relic_util.h b/contrib/relic/include/relic_util.h index d3522cc13..9fc54f703 100644 --- a/contrib/relic/include/relic_util.h +++ b/contrib/relic/include/relic_util.h @@ -115,6 +115,13 @@ */ #define RLC_HIGH(D) (D >> (RLC_DIG >> 1)) +/** + * Returns the sign bit of a digit. + * + * @param[in] D - the digit. + */ +#define RLC_SIGN(D) (((dig_t)D) >> (RLC_DIG - 1)) + /** * Selects between two values based on the value of a given flag. * @@ -162,6 +169,68 @@ #define __OPT(_1, _2, N, ...) N /** @} */ +/** + * Generic macro to initialize an object to NULL. + * + * @param[out] A - the object to initialize. + */ +#if ALLOC == AUTO +#define RLC_NULL(A) /* empty */ +#else +#define RLC_NULL(A) A = NULL; +#endif + + +/** + * Accumulates a double precision digit in a triple register variable. + * + * @param[in,out] R2 - most significant word of the triple register. + * @param[in,out] R1 - middle word of the triple register. + * @param[in,out] R0 - lowest significant word of the triple register. + * @param[in] A - the first digit to multiply. + * @param[in] B - the second digit to multiply. + */ +#define RLC_COMBA_STEP_MUL(R2, R1, R0, A, B) \ + dig_t _r, _r0, _r1; \ + RLC_MUL_DIG(_r1, _r0, A, B); \ + RLC_COMBA_ADD(_r, R2, R1, R0, _r0); \ + (R1) += _r1; \ + (R2) += (R1) < _r1; \ + +/** + * Computes the step of a Comba squaring. + * + * @param[in,out] R2 - most significant word of the triple register. + * @param[in,out] R1 - middle word of the triple register. + * @param[in,out] R0 - lowest significant word of the triple register. + * @param[in] A - the first digit to multiply. + * @param[in] B - the second digit to multiply. + */ +#define RLC_COMBA_STEP_SQR(R2, R1, R0, A, B) \ + dig_t _r, _r0, _r1; \ + RLC_MUL_DIG(_r1, _r0, A, B); \ + dig_t _s0 = _r0 + _r0; \ + dig_t _s1 = _r1 + _r1 + (_s0 < _r0); \ + RLC_COMBA_ADD(_r, R2, R1, R0, _s0); \ + (R1) += _s1; \ + (R2) += (R1) < _s1; \ + (R2) += (_s1 < _r1); \ + +/** + * Accumulates a single precision digit in a triple register variable. + * + * @param[in,out] T - the temporary variable. + * @param[in,out] R2 - most significant word of the triple register. + * @param[in,out] R1 - middle word of the triple register. + * @param[in,out] R0 - lowest significant word of the triple register. + * @param[in] A - the first digit to accumulate. + */ +#define RLC_COMBA_ADD(T, R2, R1, R0, A) \ + (T) = (R1); \ + (R0) += (A); \ + (R1) += (R0) < (A); \ + (R2) += (R1) < (T); \ + /** * Selects a real or dummy printing function depending on library flags. * diff --git a/contrib/relic/preset/ardue-ecc-128k.sh b/contrib/relic/preset/ardue-ecc-128k.sh new file mode 100755 index 000000000..a7f4616ce --- /dev/null +++ b/contrib/relic/preset/ardue-ecc-128k.sh @@ -0,0 +1,3 @@ +#!/bin/sh +ARDUINO=${HOME}/.arduino15/packages/arduino/ +CC="${ARDUINO}/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-gcc" CXX="${ARDUINO}/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-g++ -nostdlib" LDFLAGS="-mthumb -Wl,--gc-sections" CFLAGS="-nostdlib -std=c99 -Wl,--no-export-dynamic -O2 -ggdb -DF_CPU=84000000L -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections" cmake -DCMAKE_SYSTEM_NAME="Generic" -DARCH=ARM -DWSIZE=32 -DOPSYS=DUINO -DSEED=LIBC -DSHLIB=OFF -DSTBIN=ON -DTIMER=HREAL -DWITH="DV;BN;FP;EP;EC;CP;MD" -DBENCH=20 -DTESTS=20 -DCHECK=off -DVERBS=off -DSTRIP=on -DQUIET=off -DARITH=easy -DBN_METHD="COMBA;COMBA;BASIC;BASIC;STEIN;BASIC" -DBN_PRECI=3072 -DBN_MAGNI=DOUBLE -DFP_PRIME=256 -DFP_METHD="INTEG;COMBA;COMBA;QUICK;EXGCD;LOWER;SLIDE" -DEP_ENDOM=on -DEP_PLAIN=off -DEP_SUPER=off -DEC_ENDOM=on -DEC_METHD="PRIME" -DMD_METHD=SH256 $1 diff --git a/contrib/relic/preset/fiat-pbc-bls381.sh b/contrib/relic/preset/fiat-pbc-bls381.sh index 1b8b8bc1c..51143840f 100755 --- a/contrib/relic/preset/fiat-pbc-bls381.sh +++ b/contrib/relic/preset/fiat-pbc-bls381.sh @@ -1,2 +1,2 @@ -#!/bin/sh -cmake -DCHECK=off -DARITH=x64-fiat-381 -DFP_PRIME=381 -DFP_QNRES=on -DFP_METHD="BASIC;COMBA;COMBA;MONTY;LOWER;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" $1 +#!/bin/sh +cmake -DCHECK=off -DARITH=x64-fiat-381 -DFP_PRIME=381 -DFP_QNRES=on -DFP_METHD="BASIC;COMBA;COMBA;MONTY;LOWER;LOWER;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" $1 diff --git a/contrib/relic/preset/gmp-ecc-128.sh b/contrib/relic/preset/gmp-ecc-128.sh index 971c66e21..d2d1516f0 100755 --- a/contrib/relic/preset/gmp-ecc-128.sh +++ b/contrib/relic/preset/gmp-ecc-128.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DCHECK=off -DARITH=gmp -DFP_PRIME=256 -DFP_QNRES=off -DEC_METHD="PRIME" -DFP_METHD="INTEG;COMBA;COMBA;MONTY;MONTY;SLIDE" -DCFLAGS="-O2 -funroll-loops -fomit-frame-pointer" $1 +cmake -DCHECK=off -DARITH=gmp -DFP_PRIME=255 -DFP_QNRES=off -DEC_METHD="EDDIE" -DFP_METHD="INTEG;COMBA;COMBA;MONTY;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -march=native -mtune=native" $1 diff --git a/contrib/relic/preset/gmp-pbc-bls381.sh b/contrib/relic/preset/gmp-pbc-bls381.sh index 391b8a367..251793fa0 100755 --- a/contrib/relic/preset/gmp-pbc-bls381.sh +++ b/contrib/relic/preset/gmp-pbc-bls381.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DCHECK=off -DARITH=gmp -DFP_PRIME=381 -DFP_QNRES=on -DFP_METHD="BASIC;COMBA;COMBA;MONTY;LOWER;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O2 -funroll-loops -fomit-frame-pointer" -DWITH="DV;MD;BC;BN;FP;FPX;EP;EPC;EC;PP;PC;CP" $1 +cmake -DCHECK=off -DARITH=gmp -DFP_PRIME=381 -DFP_QNRES=on -DFP_METHD="BASIC;COMBA;COMBA;MONTY;LOWER;LOWER;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O2 -funroll-loops -fomit-frame-pointer" -DWITH="DV;MD;BC;BN;FP;FPX;EP;EPC;EC;PP;PC;CP" $1 diff --git a/contrib/relic/preset/gmp-pbc-bn254.sh b/contrib/relic/preset/gmp-pbc-bn254.sh index c0786d94d..bcd1a144d 100755 --- a/contrib/relic/preset/gmp-pbc-bn254.sh +++ b/contrib/relic/preset/gmp-pbc-bn254.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DARCH=X86 -DWSIZE=32 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=gmp -DFP_PRIME=254 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" $1 +cmake -DARCH=X86 -DWSIZE=32 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=gmp -DFP_PRIME=254 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/gmp-pbc-ss1536.sh b/contrib/relic/preset/gmp-pbc-ss1536.sh index db81fab76..e08dbb044 100755 --- a/contrib/relic/preset/gmp-pbc-ss1536.sh +++ b/contrib/relic/preset/gmp-pbc-ss1536.sh @@ -1,2 +1,2 @@ -#!/bin/sh -cmake -DCHECK=off -DARITH=gmp -DBN_PRECI=1536 -DFP_PRIME=1536 -DFP_QNRES=on -DFP_METHD="BASIC;COMBA;COMBA;MONTY;LOWER;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O2 -funroll-loops -fomit-frame-pointer" $1 +#!/bin/sh +cmake -DCHECK=off -DARITH=gmp -DBN_PRECI=1536 -DFP_PRIME=1536 -DFP_QNRES=on -DFP_METHD="BASIC;COMBA;COMBA;MONTY;LOWER;LOWER;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O2 -funroll-loops -fomit-frame-pointer" $1 diff --git a/contrib/relic/preset/msp-ecc-128.sh b/contrib/relic/preset/msp-ecc-128.sh index c5acfc9e1..1eea7028a 100755 --- a/contrib/relic/preset/msp-ecc-128.sh +++ b/contrib/relic/preset/msp-ecc-128.sh @@ -1,2 +1,2 @@ #!/bin/sh -CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEP_DEPTH=3 -DEP_PLAIN=ON -DEP_ENDOM=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,-mmcu=msp430f1611 -Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=256 -DBN_PRECI=256 -DMD_METHD=SH256 "-DWITH=FP;EP;EC;DV;CP;MD;BN" -DEC_ENDOM=OFF -DEC_METHD=PRIME -DRAND=HASHD $1 +CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEP_DEPTH=3 -DEP_PLAIN=ON -DEP_ENDOM=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,-mmcu=msp430f1611 -Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=256 -DBN_PRECI=256 -DMD_METHD=SH256 "-DWITH=FP;EP;EC;DV;CP;MD;BN" -DEC_ENDOM=OFF -DEC_METHD=PRIME -DRAND=HASHD $1 diff --git a/contrib/relic/preset/msp-ecc-128k.sh b/contrib/relic/preset/msp-ecc-128k.sh index 832a59c56..3a5d6a8b8 100755 --- a/contrib/relic/preset/msp-ecc-128k.sh +++ b/contrib/relic/preset/msp-ecc-128k.sh @@ -1,2 +1,2 @@ #!/bin/sh -CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEB_DEPTH=3 -DEB_PLAIN=OFF -DEP_DEPTH=3 -DEP_PLAIN=OFF "-DFB_METHD=LODAH;RLC_TABLE;QUICK;QUICK;BASIC;BASIC;EXGCD;BASIC;BASIC" -DFB_PRECO=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=256 -DFB_POLYN=283 -DBN_PRECI=284 -DMD_METHD=SH256 "-DWITH=FP;FB;EP;EB;EC;DV;CP;MD;BN" -DEC_METHD=PRIME -DRAND=HASHD $1 +CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEB_DEPTH=3 -DEB_PLAIN=OFF -DEP_DEPTH=3 -DEP_PLAIN=OFF "-DFB_METHD=LODAH;RLC_TABLE;QUICK;QUICK;BASIC;BASIC;EXGCD;BASIC;BASIC" -DFB_PRECO=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=256 -DFB_POLYN=283 -DBN_PRECI=284 -DMD_METHD=SH256 "-DWITH=FP;FB;EP;EB;EC;DV;CP;MD;BN" -DEC_METHD=PRIME -DRAND=HASHD $1 diff --git a/contrib/relic/preset/msp-ecc-80.sh b/contrib/relic/preset/msp-ecc-80.sh index caccf1ad5..6072c2534 100755 --- a/contrib/relic/preset/msp-ecc-80.sh +++ b/contrib/relic/preset/msp-ecc-80.sh @@ -1,2 +1,2 @@ #!/bin/sh -CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEP_DEPTH=3 -DEP_PLAIN=ON -DEP_ENDOM=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=160 -DBN_PRECI=160 -DMD_METHD=SH256 "-DWITH=FP;EP;EC;DV;CP;MD;BN" -DEC_ENDOM=OFF -DEC_METHD=PRIME -DRAND=HASHD $1 +CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEP_DEPTH=3 -DEP_PLAIN=ON -DEP_ENDOM=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=160 -DBN_PRECI=160 -DMD_METHD=SH256 "-DWITH=FP;EP;EC;DV;CP;MD;BN" -DEC_ENDOM=OFF -DEC_METHD=PRIME -DRAND=HASHD $1 diff --git a/contrib/relic/preset/msp-ecc-80k.sh b/contrib/relic/preset/msp-ecc-80k.sh index fdaf8ab58..42126a7d4 100755 --- a/contrib/relic/preset/msp-ecc-80k.sh +++ b/contrib/relic/preset/msp-ecc-80k.sh @@ -1,2 +1,2 @@ #!/bin/sh -CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEB_DEPTH=3 -DEB_PLAIN=OFF -DEP_DEPTH=3 -DEP_PLAIN=OFF "-DFB_METHD=LODAH;RLC_TABLE;QUICK;QUICK;BASIC;BASIC;EXGCD;BASIC;BASIC" -DFB_PRECO=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=160 -DFB_POLYN=163 -DBN_PRECI=164 -DMD_METHD=SH256 "-DWITH=FP;FB;EP;EB;EC;DV;CP;MD;BN" -DEC_METHD=PRIME -DRAND=HASHD $1 +CC="msp430-gcc -mmcu=msp430f1611" CXX="c++" cmake -DARITH=msp-asm -DCMAKE_SYSTEM_NAME=Generic -DALIGN=2 -DARCH=MSP -DBENCH=1 "-DBN_METHD=BASIC;MULTP;MONTY;BASIC;BASIC;BASIC" -DCHECK=OFF -DCOLOR=OFF "-DCFLAGS:STRING=-O2 -g -mmcu=msp430f1611 -ffunction-sections -fdata-sections -fno-inline -mdisable-watchdog" -DDOCUM=OFF -DEB_DEPTH=3 -DEB_PLAIN=OFF -DEP_DEPTH=3 -DEP_PLAIN=OFF "-DFB_METHD=LODAH;RLC_TABLE;QUICK;QUICK;BASIC;BASIC;EXGCD;BASIC;BASIC" -DFB_PRECO=OFF "-DFP_METHD=BASIC;COMBA;COMBA;QUICK;LOWER;BASIC;BASIC" -DFP_PMERS=ON "-DLDFLAGS=-Wl,--gc-sections" -DSEED= -DSHLIB=OFF -DSTRIP=ON -DTESTS=1 -DTIMER=CYCLE -DVERBS=OFF -DWSIZE=16 -DFP_PRIME=160 -DFB_POLYN=163 -DBN_PRECI=164 -DMD_METHD=SH256 "-DWITH=FP;FB;EP;EB;EC;DV;CP;MD;BN" -DEC_METHD=PRIME -DRAND=HASHD $1 diff --git a/contrib/relic/preset/x64-ecc-128.sh b/contrib/relic/preset/x64-ecc-128.sh new file mode 100755 index 000000000..f96c70370 --- /dev/null +++ b/contrib/relic/preset/x64-ecc-128.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cmake -DCHECK=off -DARITH=x64-asm-4l -DFP_PRIME=255 -DFP_QNRES=off -DEC_METHD="EDDIE" -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -march=native -mtune=native" $1 diff --git a/contrib/relic/preset/x64-pbc-bls12-381.sh b/contrib/relic/preset/x64-pbc-bls12-381.sh index 93183420d..757e67612 100755 --- a/contrib/relic/preset/x64-pbc-bls12-381.sh +++ b/contrib/relic/preset/x64-pbc-bls12-381.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-382 -DFP_PRIME=381 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" -DWITH="DV;MD;BC;BN;FP;FPX;EP;EPX;EC;PP;PC;CP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-6l -DFP_PRIME=381 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" -DWITH="DV;MD;BC;BN;FP;FPX;EP;EPX;EC;PP;PC;CP" $1 diff --git a/contrib/relic/preset/x64-pbc-bls12-446.sh b/contrib/relic/preset/x64-pbc-bls12-446.sh index e820b9b67..99fbf3d7b 100755 --- a/contrib/relic/preset/x64-pbc-bls12-446.sh +++ b/contrib/relic/preset/x64-pbc-bls12-446.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-446 -DFP_PRIME=446 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-446 -DFP_PRIME=446 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/x64-pbc-bls12-455.sh b/contrib/relic/preset/x64-pbc-bls12-455.sh index 1f3474bd7..63db8de49 100755 --- a/contrib/relic/preset/x64-pbc-bls12-455.sh +++ b/contrib/relic/preset/x64-pbc-bls12-455.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-455 -DFP_PRIME=455 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-455 -DFP_PRIME=455 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/x64-pbc-bls12-638.sh b/contrib/relic/preset/x64-pbc-bls12-638.sh index 20c278809..501149b0d 100755 --- a/contrib/relic/preset/x64-pbc-bls12-638.sh +++ b/contrib/relic/preset/x64-pbc-bls12-638.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-638 -DFP_PRIME=638 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-638 -DFP_PRIME=638 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/x64-pbc-bls24-509.sh b/contrib/relic/preset/x64-pbc-bls24-509.sh new file mode 100755 index 000000000..51eafeae6 --- /dev/null +++ b/contrib/relic/preset/x64-pbc-bls24-509.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-8l -DFP_PRIME=509 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" -DWITH="ALL" $1 diff --git a/contrib/relic/preset/x64-pbc-bls48-575.sh b/contrib/relic/preset/x64-pbc-bls48-575.sh index b6ae8cc8b..83c171bcd 100755 --- a/contrib/relic/preset/x64-pbc-bls48-575.sh +++ b/contrib/relic/preset/x64-pbc-bls48-575.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-nine -DFP_PRIME=575 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-9l -DFP_PRIME=575 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/x64-pbc-bn254.sh b/contrib/relic/preset/x64-pbc-bn254.sh index cf5737eb4..b3a0924cd 100755 --- a/contrib/relic/preset/x64-pbc-bn254.sh +++ b/contrib/relic/preset/x64-pbc-bn254.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-254 -DFP_PRIME=254 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-4l -DFP_PRIME=254 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/x64-pbc-bn382.sh b/contrib/relic/preset/x64-pbc-bn382.sh index 6c76642c3..bb3094695 100755 --- a/contrib/relic/preset/x64-pbc-bn382.sh +++ b/contrib/relic/preset/x64-pbc-bn382.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-382 -DFP_PRIME=382 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-6l -DFP_PRIME=382 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=on -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/preset/x64-pbc-bn446.sh b/contrib/relic/preset/x64-pbc-bn446.sh index 0d6cce619..4ec7373ba 100755 --- a/contrib/relic/preset/x64-pbc-bn446.sh +++ b/contrib/relic/preset/x64-pbc-bn446.sh @@ -1,2 +1,2 @@ #!/bin/sh -cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-446 -DFP_PRIME=446 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=off -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=x64-asm-446 -DFP_PRIME=446 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;LOWER;LOWER;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=off -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/contrib/relic/src/CMakeLists.txt b/contrib/relic/src/CMakeLists.txt index b98748641..c9f726cb6 100644 --- a/contrib/relic/src/CMakeLists.txt +++ b/contrib/relic/src/CMakeLists.txt @@ -115,29 +115,38 @@ if (WITH_CP) list(APPEND RELIC_SRCS "cp/relic_cp_bdpe.c") list(APPEND RELIC_SRCS "cp/relic_cp_ghpe.c") list(APPEND RELIC_SRCS "cp/relic_cp_phpe.c") - endif(WITH_BN) - if (WITH_EB OR WITH_EP OR WITH_ED) + endif() + if (WITH_EB OR WITH_EP OR WITH_ED OR WITH_EC) list(APPEND RELIC_SRCS "cp/relic_cp_ecdh.c") list(APPEND RELIC_SRCS "cp/relic_cp_ecmqv.c") list(APPEND RELIC_SRCS "cp/relic_cp_ecies.c") list(APPEND RELIC_SRCS "cp/relic_cp_ecdsa.c") list(APPEND RELIC_SRCS "cp/relic_cp_ecss.c") list(APPEND RELIC_SRCS "cp/relic_cp_vbnn.c") - endif(WITH_EB OR WITH_EP OR WITH_ED) - if (WITH_PP) + list(APPEND RELIC_SRCS "cp/relic_cp_pok.c") + list(APPEND RELIC_SRCS "cp/relic_cp_sok.c") + list(APPEND RELIC_SRCS "cp/relic_cp_ers.c") + list(APPEND RELIC_SRCS "cp/relic_cp_smlers.c") + list(APPEND RELIC_SRCS "cp/relic_cp_etrs.c") + endif() + if (WITH_PP OR WITH_PC) + list(APPEND RELIC_SRCS "cp/relic_cp_pcdel.c") list(APPEND RELIC_SRCS "cp/relic_cp_sokaka.c") list(APPEND RELIC_SRCS "cp/relic_cp_bgn.c") list(APPEND RELIC_SRCS "cp/relic_cp_ibe.c") list(APPEND RELIC_SRCS "cp/relic_cp_bls.c") list(APPEND RELIC_SRCS "cp/relic_cp_cls.c") list(APPEND RELIC_SRCS "cp/relic_cp_pss.c") - list(APPEND RELIC_SRCS "cp/relic_cp_mpss.c") list(APPEND RELIC_SRCS "cp/relic_cp_bbs.c") list(APPEND RELIC_SRCS "cp/relic_cp_zss.c") list(APPEND RELIC_SRCS "cp/relic_cp_cmlhs.c") list(APPEND RELIC_SRCS "cp/relic_cp_mklhs.c") - endif(WITH_PP) -endif(WITH_CP) + list(APPEND RELIC_SRCS "cp/relic_cp_lapsi.c") + endif() + if (WITH_MPC) + list(APPEND RELIC_SRCS "cp/relic_cp_mpss.c") + endif() +endif() if (WITH_BC) list(APPEND RELIC_SRCS ${BC_SRCS}) diff --git a/contrib/relic/src/bn/relic_bn_inv.c b/contrib/relic/src/bn/relic_bn_inv.c index 947f7c3e2..1cae05b60 100644 --- a/contrib/relic/src/bn/relic_bn_inv.c +++ b/contrib/relic/src/bn/relic_bn_inv.c @@ -63,3 +63,50 @@ void bn_mod_inv(bn_t c, const bn_t a, const bn_t b) { bn_free(u); } } + +void bn_mod_inv_sim(bn_t *c, const bn_t *a, const bn_t b, int n) { + int i; + bn_t u, *t = RLC_ALLOCA(bn_t, n); + + bn_null(u); + + RLC_TRY { + if (t == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < n; i++) { + bn_null(t[i]); + bn_new(t[i]); + } + bn_new(u); + + bn_copy(c[0], a[0]); + bn_copy(t[0], a[0]); + + for (i = 1; i < n; i++) { + bn_copy(t[i], a[i]); + bn_mul(c[i], c[i - 1], a[i]); + bn_mod(c[i], c[i], b); + } + + bn_mod_inv(u, c[n - 1], b); + + for (i = n - 1; i > 0; i--) { + bn_mul(c[i], u, c[i - 1]); + bn_mod(c[i], c[i], b); + bn_mul(u, u, t[i]); + bn_mod(u, u, b); + } + bn_copy(c[0], u); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < n; i++) { + bn_free(t[i]); + } + bn_free(u); + RLC_FREE(t); + } +} diff --git a/contrib/relic/src/bn/relic_bn_mem.c b/contrib/relic/src/bn/relic_bn_mem.c index a74eab930..f378432ad 100644 --- a/contrib/relic/src/bn/relic_bn_mem.c +++ b/contrib/relic/src/bn/relic_bn_mem.c @@ -41,7 +41,7 @@ /* Public definitions */ /*============================================================================*/ -void bn_init(bn_t a, int digits) { +void bn_make(bn_t a, int digits) { if (digits < 0) { RLC_THROW(ERR_NO_VALID); } @@ -85,7 +85,8 @@ void bn_init(bn_t a, int digits) { } #endif if (a != NULL) { - a->used = 0; + a->used = 1; + a->dp[0] = 0; a->alloc = digits; a->sign = RLC_POS; } diff --git a/contrib/relic/src/bn/relic_bn_mod.c b/contrib/relic/src/bn/relic_bn_mod.c index 387691ecd..e0d0e6cd1 100644 --- a/contrib/relic/src/bn/relic_bn_mod.c +++ b/contrib/relic/src/bn/relic_bn_mod.c @@ -169,7 +169,7 @@ void bn_mod_pre_monty(bn_t u, const bn_t m) { #if WSIZE > 16 x *= (dig_t)2 - b * x; /* here x*a==1 mod 2**32 */ #endif -#if WSIZE == 64 +#if WSIZE > 32 x *= (dig_t)2 - b * x; /* here x*a==1 mod 2**64 */ #endif /* u = -1/m0 (mod 2^RLC_DIG) */ diff --git a/contrib/relic/src/bn/relic_bn_mxp.c b/contrib/relic/src/bn/relic_bn_mxp.c index d0c4ac843..5e892b934 100644 --- a/contrib/relic/src/bn/relic_bn_mxp.c +++ b/contrib/relic/src/bn/relic_bn_mxp.c @@ -299,20 +299,11 @@ void bn_mxp_monty(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_copy(u, tab[0]); #endif - /* Silly branchless code, since called functions not constant-time. */ - bn_mod_inv(tab[0], u, m); - dv_swap_cond(u->dp, tab[0]->dp, RLC_BN_DIGS, bn_sign(b) == RLC_NEG); if (bn_sign(b) == RLC_NEG) { - u->sign = tab[0]->sign; - if (bn_cmp_dig(tab[1], 1) != RLC_EQ) { - bn_zero(c); - RLC_THROW(ERR_NO_VALID); - } + bn_mod_inv(c, u, m); + } else { + bn_copy(c, u); } - bn_add(tab[1], u, m); - dv_swap_cond(u->dp, tab[1]->dp, RLC_BN_DIGS, bn_sign(b) == RLC_NEG && bn_sign(u) == RLC_NEG); - u->sign = RLC_POS; - bn_copy(c, u); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/bn/relic_bn_prime.c b/contrib/relic/src/bn/relic_bn_prime.c index c89afa10c..eab7ff9e0 100644 --- a/contrib/relic/src/bn/relic_bn_prime.c +++ b/contrib/relic/src/bn/relic_bn_prime.c @@ -378,11 +378,13 @@ int bn_is_prime_solov(const bn_t a) { break; } - /* t2 = (t0|a). */ - bn_smb_jac(t2, t0, a); - if (bn_sign(t2) == RLC_NEG) { - bn_add(t2, t2, a); + /* Lend result here, but restore afterwards, for t2 = (t0|a). */ + result = bn_smb_jac(t0, a); + bn_set_dig(t2, (result < 0 ? -result : result)); + if (result < 0) { + bn_neg(t2, t2); } + result = 1; /* If t1 != t2 (mod a) return 0. */ bn_mod(t1, t1, a); bn_mod(t2, t2, a); diff --git a/contrib/relic/src/bn/relic_bn_rec.c b/contrib/relic/src/bn/relic_bn_rec.c index 1c9bcd2bd..a67db496f 100644 --- a/contrib/relic/src/bn/relic_bn_rec.c +++ b/contrib/relic/src/bn/relic_bn_rec.c @@ -102,6 +102,8 @@ void bn_rec_win(uint8_t *win, int *len, const bn_t k, int w) { return; } + memset(win, 0, *len); + j = 0; for (i = 0; i < l - w; i += w) { win[j++] = get_bits(k, i, i + w - 1); @@ -121,6 +123,8 @@ void bn_rec_slw(uint8_t *win, int *len, const bn_t k, int w) { return; } + memset(win, 0, *len); + i = l - 1; j = 0; while (i >= 0) { @@ -160,6 +164,8 @@ void bn_rec_naf(int8_t *naf, int *len, const bn_t k, int w) { mask = RLC_MASK(w); l = (1 << w); + memset(naf, 0, *len); + i = 0; if (w == 2) { while (!bn_is_zero(t)) { @@ -438,6 +444,8 @@ void bn_rec_tnaf(int8_t *tnaf, int *len, const bn_t k, int8_t u, int m, int w) { bn_new(r1); bn_new(tmp); + memset(tnaf, 0, *len); + bn_rec_tnaf_get(&t_w, beta, gama, u, w); bn_abs(tmp, k); bn_rec_tnaf_mod(r0, r1, tmp, u, m); @@ -565,6 +573,8 @@ void bn_rec_rtnaf(int8_t *tnaf, int *len, const bn_t k, int8_t u, int m, int w) bn_new(r1); bn_new(tmp); + memset(tnaf, 0, *len); + bn_rec_tnaf_get(&t_w, beta, gama, u, w); bn_abs(tmp, k); bn_rec_tnaf_mod(r0, r1, tmp, u, m); @@ -704,6 +714,8 @@ void bn_rec_reg(int8_t *naf, int *len, const bn_t k, int n, int w) { bn_new(t); bn_abs(t, k); + memset(naf, 0, *len); + i = 0; if (w == 2) { for (i = 0; i < l; i++) { @@ -740,15 +752,15 @@ void bn_rec_jsf(int8_t *jsf, int *len, const bn_t k, const bn_t l) { int8_t u0, u1, d0, d1; int i, j, offset; - bn_null(n0); - bn_null(n1); - if (*len < (2 * bn_bits(k) + 1)) { *len = 0; RLC_THROW(ERR_NO_BUFFER); return; } + bn_null(n0); + bn_null(n1); + RLC_TRY { bn_new(n0); bn_new(n1); @@ -760,6 +772,8 @@ void bn_rec_jsf(int8_t *jsf, int *len, const bn_t k, const bn_t l) { j = bn_bits(l); offset = RLC_MAX(i, j) + 1; + memset(jsf, 0, *len); + i = 0; d0 = d1 = 0; while (!(bn_is_zero(n0) && d0 == 0) || !(bn_is_zero(n1) && d1 == 0)) { @@ -857,3 +871,154 @@ void bn_rec_glv(bn_t k0, bn_t k1, const bn_t k, const bn_t n, const bn_t *v1, bn_free(t); } } + +void bn_rec_frb(bn_t *ki, int sub, const bn_t k, const bn_t x, const bn_t n, + int bls) { + int i, l, sk, sx; + bn_t u[4], v[4]; + + RLC_TRY { + for (i = 0; i < 4; i++) { + bn_null(u[i]); + bn_null(v[i]); + bn_new(u[i]); + bn_new(v[i]); + } + + if (bls) { + bn_abs(v[0], k); + bn_abs(u[0], x); + + sk = bn_sign(k); + sx = bn_sign(x); + + for (i = 0; i < sub; i++) { + bn_mod(ki[i], v[0], u[0]); + bn_div(v[0], v[0], u[0]); + if ((sx == RLC_NEG) && (i % 2 != 0)) { + bn_neg(ki[i], ki[i]); + } + if (sk == RLC_NEG) { + bn_neg(ki[i], ki[i]); + } + } + } else { + bn_copy(v[1], x); + bn_copy(v[2], x); + bn_copy(v[3], x); + + /* t = 2x^2. */ + bn_sqr(u[3], x); + bn_dbl(u[3], u[3]); + + /* v0 = 2x^2 + 3x + 1. */ + bn_mul_dig(v[0], x, 3); + bn_add_dig(v[0], v[0], 1); + bn_add(v[0], v[0], u[3]); + + /* v3 = -(2x^2 + x). */ + bn_add(v[3], v[3], u[3]); + bn_neg(v[3], v[3]); + + /* v1 = 12x^3 + 8x^2 + x, v2 = 6x^3 + 4x^2 + x. */ + bn_dbl(u[3], u[3]); + bn_add(v[2], v[2], u[3]); + bn_dbl(u[3], u[3]); + bn_add(v[1], v[1], u[3]); + bn_rsh(u[3], u[3], 2); + bn_mul(u[3], u[3], x); + bn_mul_dig(u[3], u[3], 3); + bn_add(v[2], v[2], u[3]); + bn_dbl(u[3], u[3]); + bn_add(v[1], v[1], u[3]); + + for (i = 0; i < 4; i++) { + bn_mul(v[i], v[i], k); + bn_div(v[i], v[i], n); + if (bn_sign(v[i]) == RLC_NEG) { + bn_add_dig(v[i], v[i], 1); + } + } + + /* u0 = x + 1, u1 = 2x + 1, u2 = 2x, u3 = x - 1. */ + bn_dbl(u[2], x); + bn_add_dig(u[1], u[2], 1); + bn_sub_dig(u[3], x, 1); + bn_add_dig(u[0], x, 1); + bn_copy(ki[0], k); + bn_zero(ki[1]); + bn_zero(ki[2]); + bn_zero(ki[3]); + for (i = 0; i < 4; i++) { + bn_mul(u[i], u[i], v[i]); + bn_mod(u[i], u[i], n); + bn_add(ki[0], ki[0], n); + bn_sub(ki[0], ki[0], u[i]); + bn_mod(ki[0], ki[0], n); + } + + /* u0 = x, u1 = -x, u2 = 2x + 1, u3 = 4x + 2. */ + bn_copy(u[0], x); + bn_neg(u[1], x); + bn_dbl(u[2], x); + bn_add_dig(u[2], u[2], 1); + bn_dbl(u[3], u[2]); + for (i = 0; i < 4; i++) { + bn_mul(u[i], u[i], v[i]); + bn_mod(u[i], u[i], n); + bn_add(ki[1], ki[1], n); + bn_sub(ki[1], ki[1], u[i]); + bn_mod(ki[1], ki[1], n); + } + + /* u0 = x, u1 = -(x + 1), u2 = 2x + 1, u3 = -(2x - 1). */ + bn_copy(u[0], x); + bn_add_dig(u[1], x, 1); + bn_neg(u[1], u[1]); + bn_dbl(u[2], x); + bn_add_dig(u[2], u[2], 1); + bn_sub_dig(u[3], u[2], 2); + bn_neg(u[3], u[3]); + for (i = 0; i < 4; i++) { + bn_mul(u[i], u[i], v[i]); + bn_mod(u[i], u[i], n); + bn_add(ki[2], ki[2], n); + bn_sub(ki[2], ki[2], u[i]); + bn_mod(ki[2], ki[2], n); + } + + /* u0 = -2x, u1 = -x, u2 = 2x + 1, u3 = x - 1. */ + bn_dbl(u[0], x); + bn_neg(u[0], u[0]); + bn_dbl(u[2], x); + bn_add_dig(u[2], u[2], 1); + bn_sub_dig(u[3], x, 1); + bn_neg(u[1], x); + for (i = 0; i < 4; i++) { + bn_mul(u[i], u[i], v[i]); + bn_mod(u[i], u[i], n); + bn_add(ki[3], ki[3], n); + bn_sub(ki[3], ki[3], u[i]); + bn_mod(ki[3], ki[3], n); + } + + for (i = 0; i < 4; i++) { + l = bn_bits(ki[i]); + bn_sub(ki[i], n, ki[i]); + if (bn_bits(ki[i]) > l) { + bn_sub(ki[i], ki[i], n); + ki[i]->sign = RLC_POS; + } else { + ki[i]->sign = RLC_NEG; + } + } + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + for (i = 0; i < 4; i++) { + bn_free(u[i]); + bn_free(v[i]); + } + } +} diff --git a/contrib/relic/src/bn/relic_bn_smb.c b/contrib/relic/src/bn/relic_bn_smb.c index 1fc977694..6c297608a 100644 --- a/contrib/relic/src/bn/relic_bn_smb.c +++ b/contrib/relic/src/bn/relic_bn_smb.c @@ -35,19 +35,19 @@ /* Public definitions */ /*============================================================================*/ -void bn_smb_leg(bn_t c, const bn_t a, const bn_t b) { +int bn_smb_leg(const bn_t a, const bn_t b) { bn_t t; + int res; bn_null(t); if (bn_sign(b) == RLC_NEG) { RLC_THROW(ERR_NO_VALID); - return; + return 0; } if (bn_cmp(a, b) == RLC_EQ) { - bn_zero(c); - return; + return 0; } RLC_TRY { @@ -56,11 +56,14 @@ void bn_smb_leg(bn_t c, const bn_t a, const bn_t b) { /* t = (b - 1)/2. */ bn_sub_dig(t, b, 1); bn_rsh(t, t, 1); - bn_mxp(c, a, t, b); - bn_sub_dig(t, b, 1); - if (bn_cmp(c, t) == RLC_EQ) { - bn_set_dig(c, 1); - bn_neg(c, c); + bn_mxp(t, a, t, b); + res = 0; + if (bn_cmp_dig(t, 1) == RLC_EQ) { + res = 1; + } + bn_sub(t, b, t); + if (bn_cmp_dig(t, 1) == RLC_EQ) { + res = -1; } } RLC_CATCH_ANY { @@ -69,11 +72,13 @@ void bn_smb_leg(bn_t c, const bn_t a, const bn_t b) { RLC_FINALLY { bn_free(t); } + + return res; } -void bn_smb_jac(bn_t c, const bn_t a, const bn_t b) { +int bn_smb_jac(const bn_t a, const bn_t b) { bn_t t0, t1, r; - int t, h; + int t, h, res; bn_null(t0); bn_null(t1); @@ -82,7 +87,7 @@ void bn_smb_jac(bn_t c, const bn_t a, const bn_t b) { /* Argument b must be odd. */ if (bn_is_even(b) || bn_sign(b) == RLC_NEG) { RLC_THROW(ERR_NO_VALID); - return; + return 0; } RLC_TRY { @@ -104,13 +109,13 @@ void bn_smb_jac(bn_t c, const bn_t a, const bn_t b) { /* If a = 0 then if n = 1 return t else return 0. */ if (bn_is_zero(t0)) { if (bn_cmp_dig(t1, 1) == RLC_EQ) { - bn_set_dig(c, 1); + res = 1; if (t == -1) { - bn_neg(c, c); + res = -1; } break; } else { - bn_zero(c); + res = 0; break; } } @@ -147,4 +152,6 @@ void bn_smb_jac(bn_t c, const bn_t a, const bn_t b) { bn_free(t1); bn_free(r); } + + return res; } diff --git a/contrib/relic/src/bn/relic_bn_util.c b/contrib/relic/src/bn/relic_bn_util.c index d438b94ac..21ce00ede 100644 --- a/contrib/relic/src/bn/relic_bn_util.c +++ b/contrib/relic/src/bn/relic_bn_util.c @@ -56,6 +56,7 @@ void bn_copy(bn_t c, const bn_t a) { c->used = a->used; c->sign = a->sign; + bn_trim(c); } void bn_abs(bn_t c, const bn_t a) { diff --git a/contrib/relic/src/cp/relic_cp_bbs.c b/contrib/relic/src/cp/relic_cp_bbs.c index 15cec8ffc..1236f7875 100644 --- a/contrib/relic/src/cp/relic_cp_bbs.c +++ b/contrib/relic/src/cp/relic_cp_bbs.c @@ -30,8 +30,6 @@ */ #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_bdpe.c b/contrib/relic/src/cp/relic_cp_bdpe.c index 7dc575c39..2d60cd3c6 100644 --- a/contrib/relic/src/cp/relic_cp_bdpe.c +++ b/contrib/relic/src/cp/relic_cp_bdpe.c @@ -29,15 +29,7 @@ * @ingroup cp */ -#include - -#include "relic_core.h" -#include "relic_conf.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" +#include "relic.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_bgn.c b/contrib/relic/src/cp/relic_cp_bgn.c index 7882c2d58..a7c38193f 100644 --- a/contrib/relic/src/cp/relic_cp_bgn.c +++ b/contrib/relic/src/cp/relic_cp_bgn.c @@ -33,13 +33,7 @@ #include -#include "relic_core.h" -#include "relic_conf.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" +#include "relic.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_cmlhs.c b/contrib/relic/src/cp/relic_cp_cmlhs.c index 07638de6e..ecdc96baf 100644 --- a/contrib/relic/src/cp/relic_cp_cmlhs.c +++ b/contrib/relic/src/cp/relic_cp_cmlhs.c @@ -96,7 +96,7 @@ int cp_cmlhs_sig(g1_t sig, g2_t z, g1_t a, g1_t c, g1_t r, g2_t s, bn_t msg, g1_t t; uint8_t mac[RLC_MD_LEN]; int len, dlen = strlen(data), result = RLC_OK; - uint8_t *buf = RLC_ALLOCA(uint8_t, 1 + 4 * RLC_FP_BYTES + dlen); + uint8_t *buf = RLC_ALLOCA(uint8_t, 1 + 8 * RLC_PC_BYTES + dlen); bn_null(k); bn_null(m); @@ -151,12 +151,7 @@ int cp_cmlhs_sig(g1_t sig, g2_t z, g1_t a, g1_t c, g1_t r, g2_t s, bn_t msg, g1_add(c, c, t); g1_norm(c, c); - if (pc_map_is_type1()) { - len = 2 * RLC_FP_BYTES + 1; - } else { - len = 4 * RLC_FP_BYTES + 1; - } - + len = g2_size_bin(z, 0); g2_write_bin(buf, len, z, 0); memcpy(buf + len, data, dlen); cp_bls_sig(sig, buf, len + dlen, sk); @@ -200,7 +195,7 @@ int cp_cmlhs_ver(g1_t r, g2_t s, g1_t sig[], g2_t z[], g1_t a[], g1_t c[], gt_t e, u, v; bn_t k, n; int len, dlen = strlen(data), result = 1; - uint8_t *buf = RLC_ALLOCA(uint8_t, 1 + 4 * RLC_FP_BYTES + dlen); + uint8_t *buf = RLC_ALLOCA(uint8_t, 1 + 8 * RLC_PC_BYTES + dlen); g1_null(g1); g2_null(g2); @@ -311,7 +306,7 @@ int cp_cmlhs_onv(g1_t r, g2_t s, g1_t sig[], g2_t z[], g1_t a[], g1_t c[], gt_t e, u, v; bn_t k, n; int len, dlen = strlen(data), result = 1; - uint8_t *buf = RLC_ALLOCA(uint8_t, 1 + 4 * RLC_FP_BYTES + dlen); + uint8_t *buf = RLC_ALLOCA(uint8_t, 1 + 8 * RLC_FP_BYTES + dlen); g1_null(g1); g2_null(g2); diff --git a/contrib/relic/src/cp/relic_cp_ecdh.c b/contrib/relic/src/cp/relic_cp_ecdh.c index 31980f577..7479fa955 100755 --- a/contrib/relic/src/cp/relic_cp_ecdh.c +++ b/contrib/relic/src/cp/relic_cp_ecdh.c @@ -30,8 +30,6 @@ */ #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_ecdsa.c b/contrib/relic/src/cp/relic_cp_ecdsa.c index 97fda3cb5..c42db5182 100644 --- a/contrib/relic/src/cp/relic_cp_ecdsa.c +++ b/contrib/relic/src/cp/relic_cp_ecdsa.c @@ -30,7 +30,6 @@ */ #include "relic.h" -#include "relic_test.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_ecies.c b/contrib/relic/src/cp/relic_cp_ecies.c index 280983161..74b756997 100644 --- a/contrib/relic/src/cp/relic_cp_ecies.c +++ b/contrib/relic/src/cp/relic_cp_ecies.c @@ -29,14 +29,7 @@ * @ingroup cp */ -#include - -#include "relic_core.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" -#include "relic_bc.h" +#include "relic.h" /*============================================================================*/ /* Public definitions */ @@ -69,7 +62,7 @@ int cp_ecies_enc(ec_t r, uint8_t *out, int *out_len, uint8_t *in, int in_len, ec_t q) { bn_t k, n, x; ec_t p; - int l, result = RLC_OK, size = RLC_CEIL(ec_param_level(), 8); + int l, result = RLC_OK, size = RLC_CEIL(RLC_MAX(128, ec_param_level()), 8); uint8_t _x[RLC_FC_BYTES + 1], iv[RLC_BC_LEN] = { 0 }; uint8_t key[2 * 8 * (RLC_FC_BYTES + 1)]; @@ -124,7 +117,7 @@ int cp_ecies_dec(uint8_t *out, int *out_len, ec_t r, uint8_t *in, int in_len, ec_t p; bn_t x; - int l, result = RLC_OK, size = RLC_CEIL(ec_param_level(), 8); + int l, result = RLC_OK, size = RLC_CEIL(RLC_MAX(128, ec_param_level()), 8); uint8_t _x[RLC_FC_BYTES + 1], h[RLC_MD_LEN], iv[RLC_BC_LEN] = { 0 }; uint8_t key[2 * 8 * (RLC_FC_BYTES + 1)]; diff --git a/contrib/relic/src/cp/relic_cp_ecmqv.c b/contrib/relic/src/cp/relic_cp_ecmqv.c index fd3596ed6..5d40116fb 100644 --- a/contrib/relic/src/cp/relic_cp_ecmqv.c +++ b/contrib/relic/src/cp/relic_cp_ecmqv.c @@ -30,8 +30,6 @@ */ #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_ecss.c b/contrib/relic/src/cp/relic_cp_ecss.c index d943b8960..0ff291033 100644 --- a/contrib/relic/src/cp/relic_cp_ecss.c +++ b/contrib/relic/src/cp/relic_cp_ecss.c @@ -30,7 +30,6 @@ */ #include "relic.h" -#include "relic_test.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_elgamal.c b/contrib/relic/src/cp/relic_cp_elgamal.c deleted file mode 100644 index 7c1c80fa9..000000000 --- a/contrib/relic/src/cp/relic_cp_elgamal.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2020 RELIC Authors - * - * This file is part of RELIC. RELIC is legal property of its developers, - * whose names are not listed here. Please refer to the COPYRIGHT file - * for contact information. - * - * RELIC is free software; you can redistribute it and/or modify it under the - * terms of the version 2.1 (or later) of the GNU Lesser General Public License - * as published by the Free Software Foundation; or version 2.0 of the Apache - * License as published by the Apache Software Foundation. See the LICENSE files - * for more details. - * - * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the LICENSE files for more details. - * - * You should have received a copy of the GNU Lesser General Public or the - * Apache License along with RELIC. If not, see - * or . - */ - -/** - * @file - * - * Implementation of the ElGamal cryptosystem. - * - * @ingroup cp - */ - -#include - -#include "relic_core.h" -#include "relic_conf.h" -#include "relic_error.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" - -/*============================================================================*/ -/* Public definitions */ -/*============================================================================*/ - -int cp_elgamal_gen(elgamal_t pub, elgamal_t prv, int bits) { - int result = STS_OK; - - RLC_TRY { - /* Generate prime p. */ - bn_gen_prime(prv->q, bits); - bn_copy(pub->q, prv->q); - bn_rand(prv->x, 0, bits); - bn_rand(prv->g, 0, bits); - bn_mod_basic(prv->g, prv->g, prv->q); - bn_copy(pub->g, prv->g); - bn_mxp(pub->P, prv->g, prv->x, prv->q); - bn_copy(prv->P, pub->P); - } - RLC_CATCH_ANY { - result = STS_ERR; - } - RLC_FINALLY { - } - - return result; -} - -int cp_elgamal_enc(unsigned char *out, int *out_len, unsigned char *in, - int in_len, elgamal_t pub) { - bn_t m, b; - elgamal_cipher_t c; - int size, result = STS_OK; - - bn_null(m); - bn_null(c->c1); - bn_null(c->c2); - bn_null(b); - - bn_size_bin(&size, pub->q); - - RLC_TRY { - bn_new(m); - bn_new(c->c1); - bn_new(c->c2); - bn_new(b); - - bn_zero(m); - bn_zero(c->c1); - bn_zero(c->c2); - bn_zero(b); - - bn_read_bin(m, in, in_len); - bn_add(c->c1, c->c1, m); - - bn_rand(b, 0, size); - bn_mxp(c->c1, pub->g, b, pub->q); - bn_mxp(c->c2, pub->P, b, pub->q); - bn_mul(c->c2, m, c->c2); - bn_mod_basic(c->c2, c->c2, pub->q); - - if (size <= *out_len) { - *out_len = size; - memset(out, 0, *out_len); - bn_write_bin(out, size, c->c1); - bn_write_bin(out+size, size, c->c2); - } else { - result = STS_ERR; - } - } - RLC_CATCH_ANY { - result = STS_ERR; - } - RLC_FINALLY { - bn_free(m); - bn_free(c->c1); - bn_free(c->c2); - bn_free(b); - - } - - return result; -} - -int cp_elgamal_dec(unsigned char *out, int *out_len, unsigned char *in, - int in_len, elgamal_t prv) { - bn_t m, c1, c2, r; - int size, result = STS_OK; - - - if (in_len < 0 || in_len != size) { - return STS_ERR; - } - - bn_null(m); - bn_null(c1); - bn_null(c2); - bn_null(r); - - RLC_TRY { - bn_new(m); - bn_new(c1); - bn_new(c2); - bn_new(r); - - bn_read_bin(c1, in, size); - bn_read_bin(c2, in+size, size); - bn_mxp(c1, c1, prv->x, prv->q); - bn_gcd_ext(r, c1, NULL, c1, prv->q); //TODO verificar se r = 1 - bn_mul(m, c1, c2); - bn_mod_basic(m, m, prv->q); - - if (m->sign == BN_NEG) { - bn_add(m, m, prv->q); - } - - bn_size_bin(&size, m); - - if (bn_cmp(m, prv->q) != CMP_LT) { - result = STS_ERR; - } - - if (size <= *out_len) { - memset(out, 0, size); - bn_write_bin(out, size, m); - *out_len = size; - } - else { - result = STS_ERR; - } - } - RLC_CATCH_ANY { - result = STS_ERR; - } - RLC_FINALLY { - bn_free(m); - bn_free(c1); - bn_free(c2); - bn_free(r); - } - - return result; -} diff --git a/contrib/relic/src/cp/relic_cp_ers.c b/contrib/relic/src/cp/relic_cp_ers.c new file mode 100644 index 000000000..ecb5e805e --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_ers.c @@ -0,0 +1,195 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of extendable ring signatures. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int cp_ers_gen(ec_t pp) { + ec_rand(pp); + return RLC_OK; +} + +int cp_ers_gen_key(bn_t sk, ec_t pk) { + bn_t n; + int result = RLC_OK; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + ec_curve_get_ord(n); + bn_rand_mod(sk, n); + ec_mul_gen(pk, sk); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + } + return result; +} + +int cp_ers_sig(bn_t td, ers_t p, uint8_t *msg, int len, bn_t sk, ec_t pk, + ec_t pp) { + bn_t n; + ec_t t, y[2]; + int result = RLC_OK; + + bn_null(n); + ec_null(t); + ec_null(y[0]); + ec_null(y[1]); + + RLC_TRY { + bn_new(n); + ec_new(t); + ec_new(y[0]); + ec_new(y[1]); + + ec_curve_get_ord(n); + bn_rand_mod(td, n); + ec_mul_gen(t, td); + ec_sub(t, pp, t); + ec_norm(p->h, t); + + ec_copy(p->pk, pk); + ec_copy(y[0], p->h); + ec_copy(y[1], p->pk); + cp_sokor_sig(p->c, p->r, msg, len, y, NULL, sk, 0); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + ec_free(t); + ec_free(y[0]); + ec_free(y[1]); + } + return result; +} + +int cp_ers_ver(bn_t td, ers_t *s, int size, uint8_t *msg, int len, ec_t pp) { + bn_t n; + ec_t t, y[2]; + int flag = 0, result = 0; + + bn_null(n); + ec_null(t); + ec_null(y[0]); + ec_null(y[1]); + + RLC_TRY { + bn_new(n); + ec_new(t); + ec_new(y[0]); + ec_new(y[1]); + + ec_curve_get_ord(n); + ec_mul_gen(t, td); + + for (int i = 0; i < size; i++) { + ec_add(t, t, s[i]->h); + } + if (ec_cmp(pp, t) == RLC_EQ) { + flag = 1; + for (int i = 0; i < size; i++) { + ec_copy(y[0], s[i]->h); + ec_copy(y[1], s[i]->pk); + flag &= cp_sokor_ver(s[i]->c, s[i]->r, msg, len, y, NULL); + } + } + result = flag; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + ec_free(t); + ec_free(y[0]); + ec_free(y[1]); + } + return result; +} + +int cp_ers_ext(bn_t td, ers_t *p, int *size, uint8_t *msg, int len, ec_t pk, + ec_t pp) { + bn_t n, r; + ec_t y[2]; + int result = RLC_OK; + + bn_null(n); + bn_null(r); + ec_null(y[0]); + ec_null(y[1]); + + for (int i = 0; i < *size; i++) { + if (ec_cmp(pk, p[i]->pk) == RLC_EQ) { + return RLC_ERR; + } + } + + RLC_TRY { + bn_new(n); + bn_new(r); + ec_new(y[0]); + ec_new(y[1]); + + ec_curve_get_ord(n); + bn_rand_mod(r, n); + bn_sub(td, td, r); + bn_mod(td, td, n); + ec_mul_gen(p[*size]->h, r); + + ec_copy(p[*size]->pk, pk); + ec_copy(y[0], p[*size]->h); + ec_copy(y[1], p[*size]->pk); + cp_sokor_sig(p[*size]->c, p[*size]->r, msg, len, y, NULL, r, 1); + (*size)++; + result = RLC_OK; + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(r); + ec_free(y[0]); + ec_free(y[1]); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_etrs.c b/contrib/relic/src/cp/relic_cp_etrs.c new file mode 100644 index 000000000..d55dee871 --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_etrs.c @@ -0,0 +1,401 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of extendable ring signatures. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int cp_etrs_sig(bn_t *td, bn_t *y, int max, etrs_t p, uint8_t *msg, int len, + bn_t sk, ec_t pk, ec_t pp) { + bn_t n, l, u, v, z; + ec_t t, w[2]; + bn_t *_v = RLC_ALLOCA(bn_t, max); + int result = RLC_OK; + + bn_null(n); + bn_null(l); + bn_null(u); + bn_null(v); + bn_null(z); + ec_null(t); + ec_null(w[0]); + ec_null(w[1]); + + RLC_TRY { + bn_new(n); + bn_new(l); + bn_new(u); + bn_new(v); + bn_new(z); + ec_new(t); + ec_new(w[0]); + ec_new(w[1]); + + ec_curve_get_ord(n); + if (_v == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for(int i = 0; i < max; i++) { + bn_new(_v[i]); + bn_rand_mod(y[i], n); + bn_rand_mod(td[i], n); + } + bn_rand_mod(p->y, n); + + bn_set_dig(l, 1); + for(int j = 0; j < max; j++) { + bn_copy(_v[j], y[j]); + } + bn_mod_inv_sim(_v, _v, n, max); + for(int j = 0; j < max; j++) { + bn_sub(u, y[j], p->y); + bn_mul(u, u, _v[j]); + bn_mod(u, u, n); + bn_mul(l, l, u); + bn_mod(l, l, n); + } + ec_mul(p->h, pp, l); + for(int i = 0; i < max; i++) { + ec_mul_gen(t, td[i]); + bn_mod_inv(v, y[i], n); + bn_mul(u, v, p->y); + bn_mod(l, u, n); + for(int j = 0; j < max; j++) { + bn_set_dig(_v[j], 1); + if (j != i) { + bn_sub(_v[j], y[j], y[i]); + bn_mod(_v[j], _v[j], n); + } + } + bn_mod_inv_sim(_v, _v, n, max); + for(int j = 0; j < max; j++) { + if (j != i) { + bn_sub(u, y[j], p->y); + bn_mul(u, u, _v[j]); + bn_mod(u, u, n); + bn_mul(l, l, u); + bn_mod(l, l, n); + } + } + ec_mul(t, t, l); + ec_add(p->h, p->h, t); + } + ec_norm(p->h, p->h); + + ec_copy(p->pk, pk); + ec_copy(w[0], p->h); + ec_copy(w[1], p->pk); + cp_sokor_sig(p->c, p->r, msg, len, w, NULL, sk, 0); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(l); + bn_free(u); + bn_free(v); + bn_free(z); + ec_free(t); + ec_free(w[0]); + ec_free(w[1]); + for (int i = 0; i < max; i++) { + bn_free(_v[i]); + } + RLC_FREE(_v); + } + return result; +} + +int cp_etrs_ver(int thres, bn_t *td, bn_t *y, int max, etrs_t *s, int size, + uint8_t *msg, int len, ec_t pp) { + int i, flag = 0, result = 0; + bn_t l, n, u, v; + ec_t t, w[2]; + + int d = max + size - thres; + bn_t *_v = RLC_ALLOCA(bn_t, d); + bn_t *_y = RLC_ALLOCA(bn_t, d); + ec_t *_t = RLC_ALLOCA(ec_t, d); + + bn_null(l); + bn_null(n); + bn_null(u); + bn_null(v); + ec_null(t); + ec_null(w[0]); + ec_null(w[1]); + + RLC_TRY { + bn_new(l); + bn_new(n); + bn_new(u); + bn_new(v); + ec_new(t); + ec_new(w[0]); + ec_new(w[1]); + if (_y == NULL || _t == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < d; i++) { + bn_new(_v[i]); + bn_new(_y[i]); + ec_new(_t[i]); + } + + for (i = 0; i < max; i++) { + bn_copy(_y[i], y[i]); + ec_mul_gen(_t[i], td[i]); + } + for (; i < d; i++) { + bn_copy(_y[i], s[i - max]->y); + ec_copy(_t[i], s[i - max]->h); + } + + ec_curve_get_ord(n); + + flag = 1; + ec_set_infty(w[0]); + for(i = 0; i < d; i++) { + for(int j = 0; j < d; j++) { + bn_set_dig(_v[j], 1); + if (j != i) { + bn_sub(_v[j], _y[j], _y[i]); + bn_mod(_v[j], _v[j], n); + } + } + bn_mod_inv_sim(_v, _v, n, d); + bn_set_dig(l, 1); + for(int j = 0; j < d; j++) { + if (j != i) { + bn_mul(u, _y[j], _v[j]); + bn_mod(u, u, n); + bn_mul(l, l, u); + bn_mod(l, l, n); + } + } + + ec_mul(t, _t[i], l); + ec_add(w[0], w[0], t); + } + ec_norm(w[0], w[0]); + flag &= ec_cmp(w[0], pp) != RLC_EQ; + + for (int i = 0; i < size; i++) { + ec_copy(w[0], s[i]->h); + ec_copy(w[1], s[i]->pk); + flag &= cp_sokor_ver(s[i]->c, s[i]->r, msg, len, w, NULL); + } + result = flag; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(l); + bn_free(n); + bn_free(u); + bn_free(v); + ec_free(t); + ec_free(w[0]); + ec_free(w[1]); + for (int i = 0; i < d; i++) { + bn_free(_v[i]); + bn_free(_y[i]); + ec_free(_t[i]); + } + RLC_FREE(_v); + RLC_FREE(_y); + RLC_FREE(_t); + } + return result; +} + +int cp_etrs_ext(bn_t *td, bn_t *y, int max, etrs_t *p, int *size, uint8_t *msg, int len, + ec_t pk, ec_t pp) { + bn_t n, r; + ec_t w[2]; + int i, result = RLC_OK; + + bn_null(n); + bn_null(r); + ec_null(w[0]); + ec_null(w[1]); + + for (int i = 0; i < *size; i++) { + if (ec_cmp(pk, p[i]->pk) == RLC_EQ) { + return RLC_ERR; + } + } + + RLC_TRY { + bn_new(n); + bn_new(r); + ec_new(w[0]); + ec_new(w[1]); + + for (i = 0; i < max; i++) { + if (!bn_is_zero(td[i])) { + break; + } + } + bn_copy(r, td[i]); + + ec_curve_get_ord(n); + ec_mul_gen(p[*size]->h, td[i]); + bn_copy(p[*size]->y, y[i]); + + bn_zero(td[i]); + bn_zero(y[i]); + + ec_copy(p[*size]->pk, pk); + ec_copy(w[0], p[*size]->h); + ec_copy(w[1], p[*size]->pk); + cp_sokor_sig(p[*size]->c, p[*size]->r, msg, len, w, NULL, r, 1); + (*size)++; + result = RLC_OK; + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(r); + ec_free(w[0]); + ec_free(w[1]); + } + return result; +} + +int cp_etrs_uni(int thres, bn_t *td, bn_t *y, int max, etrs_t *p, int *size, + uint8_t *msg, int len, bn_t sk, ec_t pk, ec_t pp) { + int i, result = 0; + bn_t l, n, u, v; + ec_t t, w[2]; + + int d = max + *size; + bn_t *_v = RLC_ALLOCA(bn_t, d); + bn_t *_y = RLC_ALLOCA(bn_t, d); + ec_t *_t = RLC_ALLOCA(ec_t, d); + + bn_null(l); + bn_null(n); + bn_null(u); + bn_null(v); + ec_null(t); + ec_null(w[0]); + ec_null(w[1]); + + RLC_TRY { + bn_new(l); + bn_new(n); + bn_new(u); + bn_new(v); + ec_new(t); + ec_new(w[0]); + ec_new(w[1]); + if (_v == NULL || _y == NULL || _t == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < d; i++) { + bn_new(_v[i]); + bn_new(_y[i]); + ec_new(_t[i]); + } + + for (i = 0; i < max; i++) { + bn_copy(_y[i], y[i]); + ec_mul_gen(_t[i], td[i]); + } + for (; i < d; i++) { + bn_copy(_y[i], p[i - max]->y); + ec_copy(_t[i], p[i - max]->h); + } + + ec_curve_get_ord(n); + bn_rand_mod(p[*size]->y, n); + + ec_set_infty(p[*size]->h); + for(i = 0; i < d; i++) { + for(int j = 0; j < d; j++) { + bn_set_dig(_v[j], 1); + if (j != i) { + bn_sub(_v[j], _y[j], _y[i]); + bn_mod(_v[j], _v[j], n); + } + } + bn_mod_inv_sim(_v, _v, n, d); + bn_set_dig(l, 1); + for(int j = 0; j < d; j++) { + if (j != i) { + bn_sub(u, _y[j], p[*size]->y); + bn_mul(u, u, _v[j]); + bn_mod(u, u, n); + bn_mul(l, l, u); + bn_mod(l, l, n); + } + } + ec_mul(t, _t[i], l); + ec_add(p[*size]->h, p[*size]->h, t); + } + ec_norm(p[*size]->h, p[*size]->h); + + ec_copy(p[*size]->pk, pk); + ec_copy(w[0], p[*size]->h); + ec_copy(w[1], p[*size]->pk); + cp_sokor_sig(p[*size]->c, p[*size]->r, msg, len, w, NULL, sk, 0); + (*size)++; + result = RLC_OK; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(l); + bn_free(n); + bn_free(u); + bn_free(v); + ec_free(t); + ec_free(w[0]); + ec_free(w[1]); + for (int i = 0; i < d; i++) { + bn_free(_v[i]); + bn_free(_y[i]); + ec_free(_t[i]); + } + RLC_FREE(_v); + RLC_FREE(_y); + RLC_FREE(_t); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_ghpe.c b/contrib/relic/src/cp/relic_cp_ghpe.c index 6bfb588ea..d69edb8be 100644 --- a/contrib/relic/src/cp/relic_cp_ghpe.c +++ b/contrib/relic/src/cp/relic_cp_ghpe.c @@ -30,16 +30,7 @@ * @ingroup cp */ -#include - -#include "relic_core.h" -#include "relic_multi.h" -#include "relic_conf.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" +#include "relic.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_ibe.c b/contrib/relic/src/cp/relic_cp_ibe.c index e7af51b8b..8e6b8d50f 100644 --- a/contrib/relic/src/cp/relic_cp_ibe.c +++ b/contrib/relic/src/cp/relic_cp_ibe.c @@ -30,8 +30,6 @@ */ #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_lapsi.c b/contrib/relic/src/cp/relic_cp_lapsi.c new file mode 100644 index 000000000..facdb9ee0 --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_lapsi.c @@ -0,0 +1,205 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of protocols for laconic private set intersection. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int cp_lapsi_gen(bn_t sk, g2_t ss, g1_t s[], int m) { + int i, result = RLC_OK; + bn_t q; + + bn_null(q); + + RLC_TRY { + bn_new(q); + + pc_get_ord(q); + bn_rand_mod(sk, q); + g2_mul_gen(ss, sk); + + g1_get_gen(s[0]); + for (i = 1; i <= m; i++) { + g1_mul(s[i], s[i - 1], sk); + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(q); + } + return result; +} + +int cp_lapsi_ask(g1_t d, bn_t r, bn_t x[], g1_t s[], int m) { + int i, j, result = RLC_OK; + bn_t q, *p = RLC_ALLOCA(bn_t, m + 1), *_p = RLC_ALLOCA(bn_t, m + 1); + + bn_null(q); + + RLC_TRY { + bn_new(q); + for (i = 0; i <= m; i++) { + bn_null(p[i]); + bn_null(_p[i]); + bn_new(p[i]); + bn_new(_p[i]); + } + + pc_get_ord(q); + bn_rand_mod(r, q); + if (m == 0) { + g1_mul_gen(d, r); + } else { + bn_set_dig(p[0], 1); + for (i = 0; i < m; i++) { + bn_zero(_p[0]); + for (j = 0; j <= i; j++) { + bn_copy(_p[j + 1], p[j]); + } + for (j = 0; j <= i; j++) { + bn_mul(p[j], p[j], x[i]); + bn_mod(p[j], p[j], q); + bn_sub(p[j], _p[j], p[j]); + bn_mod(p[j], p[j], q); + } + bn_copy(p[j], _p[j]); + } + g1_mul_sim_lot(d, s, p, m + 1); + g1_mul(d, d, r); + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(q); + for (i = 0; i <= m; i++) { + bn_free(p[i]); + bn_free(_p[i]); + } + RLC_FREE(p); + RLC_FREE(_p); + } + return result; +} + +int cp_lapsi_ans(gt_t t[], g2_t u[], g1_t d, g2_t ss, bn_t y[], int n) { + int j, result = RLC_OK; + bn_t q, tj; + g1_t g1; + g2_t g2; + + bn_null(q); + bn_null(tj); + g1_null(g1); + g2_null(g2); + + RLC_TRY { + bn_new(q); + bn_new(tj); + g1_new(g1); + g2_new(g2); + + pc_get_ord(q); + g2_get_gen(g2); + for (j = 0; j < n; j++) { + bn_rand_mod(tj, q); + g1_mul(g1, d, tj); + pc_map(t[j], g1, g2); + g2_mul_gen(u[j], y[j]); + g2_sub(u[j], ss, u[j]); + g2_norm(u[j], u[j]); + g2_mul(u[j], u[j], tj); + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(q); + bn_free(tj); + g1_free(g1); + g1_free(g2); + } + return result; +} + +int cp_lapsi_int(bn_t z[], int *len, bn_t sk, g1_t d, bn_t x[], int m, + gt_t t[], g2_t u[], int n) { + int j, k, result = RLC_OK; + bn_t i, q; + g1_t c; + gt_t e; + + bn_null(i); + bn_null(q); + g1_null(c); + gt_null(e); + + RLC_TRY { + bn_new(i); + bn_new(q); + g1_new(c); + gt_new(e); + + *len = 0; + if (m > 0) { + pc_get_ord(q); + for (k = 0; k < m; k++) { + bn_sub(i, sk, x[k]); + bn_mod(i, i, q); + bn_mod_inv(i, i, q); + g1_mul(c, d, i); + for (j = 0; j < n; j++) { + pc_map(e, c, u[j]); + if (gt_cmp(e, t[j]) == RLC_EQ && !gt_is_unity(e)) { + bn_copy(z[*len], x[k]); + (*len)++; + } + } + } + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(i); + bn_free(q); + g1_free(c); + gt_free(e); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_pcdel.c b/contrib/relic/src/cp/relic_cp_pcdel.c new file mode 100644 index 000000000..a8ded35e5 --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_pcdel.c @@ -0,0 +1,461 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of pairing delegation protocols. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int cp_pdpub_gen(bn_t c, bn_t r, g1_t u1, g2_t u2, g2_t v2, gt_t e) { + bn_t n; + int result = RLC_OK; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + /* Generate random c, U1, r, U2. */ + pc_get_ord(n); + bn_rand(c, RLC_POS, 50); + g1_rand(u1); + bn_rand_mod(r, n); + g2_rand(u2); + /* Compute gamma = e(U1, U2) and V2 = [1/r2]U2. */ + bn_mod_inv(n, r, n); + g2_mul(v2, u2, n); + pc_map(e, u1, u2); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + } + return result; +} + +int cp_pdpub_ask(g1_t v1, g2_t w2, g1_t p, g2_t q, bn_t c, bn_t r, g1_t u1, g2_t u2, g2_t v2) { + int result = RLC_OK; + + /* Compute V1 = [r](P - U1). */ + g1_sub(v1, p, u1); + g1_mul(v1, v1, r); + /* Compute W2 = [c]Q + U2. */ + g2_mul(w2, q, c); + g2_add(w2, w2, u2); + + return result; +} + +int cp_pdpub_ans(gt_t g[3], g1_t p, g2_t q, g1_t v1, g2_t v2, g2_t w2) { + int result = RLC_OK; + pc_map(g[0], p, q); + pc_map(g[1], p, w2); + pc_map(g[2], v1, v2); + return result; +} + +int cp_pdpub_ver(gt_t r, gt_t g[3], bn_t c, gt_t e) { + int result = 1; + gt_t t; + + gt_null(t); + + RLC_TRY { + gt_new(t); + + result &= gt_is_valid(g[0]); + result &= gt_is_valid(g[2]); + + gt_exp(t, g[0], c); + gt_mul(t, t, g[2]); + gt_mul(t, t, e); + + if (!result || gt_cmp(t, g[1]) != RLC_EQ) { + gt_set_unity(r); + } else { + gt_copy(r, g[0]); + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + gt_free(t); + } + return result; +} + +int cp_pdprv_gen(bn_t c, bn_t r[3], g1_t u1[2], g2_t u2[2], g2_t v2[4], gt_t e[2]) { + bn_t n; + int result = RLC_OK; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + pc_get_ord(n); + bn_rand_mod(r[2], n); + bn_rand(c, RLC_POS, 50); + for (int i = 0; i < 2; i++) { + /* Generate random c, r, Ui. */ + g1_rand(u1[i]); + bn_rand_mod(r[i], n); + g2_rand(u2[i]); + /* Compute gamma = e(U1, U2) and V2 = [1/r2]U2. */ + pc_get_ord(n); + bn_mod_inv(n, r[i], n); + g2_mul(v2[i], u2[i], n); + pc_map(e[i], u1[i], u2[i]); + } + g2_mul(v2[2], u2[0], r[2]); + g2_neg(v2[2], v2[2]); + g2_mul(v2[3], u2[1], r[2]); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + } + return result; +} + +int cp_pdprv_ask(g1_t v1[3], g2_t w2[4], g1_t p, g2_t q, bn_t c, bn_t r[3], g1_t u1[2], g2_t u2[2], g2_t v2[4]) { + int result = RLC_OK; + bn_t n; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + pc_get_ord(n); + bn_mod_inv(n, r[2], n); + g1_mul(v1[2], p, n); + for (int i = 0; i < 2; i++) { + /* Compute V1 = [r](A - Ui). */ + g1_sub(v1[i], p, u1[i]); + g1_mul(v1[i], v1[i], r[i]); + } + g2_mul(w2[0], q, r[2]); + g2_add(w2[2], w2[0], v2[2]); + g2_mul(w2[3], w2[0], c); + g2_add(w2[3], w2[3], v2[3]); + g2_copy(w2[0], v2[0]); + g2_copy(w2[1], v2[1]); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(n); + } + + return result; +} + +int cp_pdprv_ans(gt_t g[4], g1_t v1[3], g2_t w2[4]) { + int result = RLC_OK; + pc_map(g[0], v1[0], w2[0]); + pc_map(g[1], v1[1], w2[1]); + pc_map(g[2], v1[2], w2[2]); + pc_map(g[3], v1[2], w2[3]); + return result; +} + +int cp_pdprv_ver(gt_t r, gt_t g[4], bn_t c, gt_t e[2]) { + int result = 1; + gt_t t; + + gt_null(t); + + RLC_TRY { + gt_new(t); + + result &= gt_is_valid(g[0]); + result &= gt_is_valid(g[1]); + result &= gt_is_valid(g[2]); + + gt_mul(t, g[0], g[2]); + gt_mul(r, t, e[0]); + gt_exp(t, r, c); + gt_mul(t, t, g[1]); + gt_mul(t, t, e[1]); + + if (!result || gt_cmp(t, g[3]) != RLC_EQ) { + gt_set_unity(r); + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + gt_free(t); + } + return result; +} + +int cp_lvpub_gen(bn_t r, g1_t u1, g2_t u2, g2_t v2, gt_t e) { + bn_t n; + int result = RLC_OK; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + /* Generate random c, U1, r, U2. */ + pc_get_ord(n); + g1_rand(u1); + bn_rand_mod(r, n); + g2_rand(u2); + /* Compute gamma = e(U1, U2) and V2 = [1/r2]U2. */ + bn_mod_inv(n, r, n); + g2_mul(v2, u2, n); + pc_map(e, u1, u2); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + } + return result; +} + +int cp_lvpub_ask(bn_t c, g1_t v1, g2_t w2, g1_t p, g2_t q, bn_t r, g1_t u1, g2_t u2, g2_t v2) { + int result = RLC_OK; + + /* Sample random c. */ + bn_rand(c, RLC_POS, 50); + /* Compute V1 = [r](P - U1). */ + g1_sub(v1, p, u1); + g1_mul(v1, v1, r); + /* Compute W2 = [c]Q + U_2. */ + g2_mul(w2, q, c); + g2_add(w2, w2, u2); + + return result; +} + +int cp_lvpub_ans(gt_t g[2], g1_t p, g2_t q, g1_t v1, g2_t v2, g2_t w2) { + int result = RLC_OK; + g1_t _p[2]; + g2_t _q[2]; + + g1_null(_p[0]); + g1_null(_p[1]); + g2_null(_q[0]); + g2_null(_q[1]); + + RLC_TRY { + g1_new(_p[0]); + g1_new(_p[1]); + g2_new(_q[0]); + g2_new(_q[1]); + + g1_copy(_p[0], p); + g1_copy(_p[1], v1); + g2_copy(_q[0], w2); + g2_neg(_q[1], v2); + pc_map_sim(g[1], _p, _q, 2); + pc_map(g[0], p, q); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + g1_free(_p[0]); + g1_free(_p[1]); + g2_free(_q[0]); + g2_free(_q[1]); + } + + return result; +} + +int cp_lvpub_ver(gt_t r, gt_t g[2], bn_t c, gt_t e) { + int result = 1; + gt_t t; + + gt_null(t); + + RLC_TRY { + gt_new(t); + + result &= gt_is_valid(g[0]); + + gt_exp(t, g[0], c); + gt_inv(t, t); + gt_mul(t, t, g[1]); + + if (!result || gt_cmp(t, e) != RLC_EQ) { + gt_set_unity(r); + } else { + gt_copy(r, g[0]); + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + gt_free(t); + } + return result; +} + +int cp_lvprv_gen(bn_t c, bn_t r[3], g1_t u1[2], g2_t u2[2], g2_t v2[4], gt_t e[2]) { + bn_t n; + int result = RLC_OK; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + pc_get_ord(n); + bn_rand_mod(r[2], n); + bn_rand(c, RLC_POS, 50); + for (int i = 0; i < 2; i++) { + /* Generate random c, r, Ui. */ + g1_rand(u1[i]); + bn_rand_mod(r[i], n); + g2_rand(u2[i]); + /* Compute gamma = e(U1, U2) and V2 = [1/r2]U2. */ + pc_get_ord(n); + bn_mod_inv(n, r[i], n); + g2_mul(v2[i], u2[i], n); + pc_map(e[i], u1[i], u2[i]); + } + g2_mul(v2[2], u2[0], r[2]); + g2_neg(v2[2], v2[2]); + g2_mul(v2[3], u2[1], r[2]); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + } + return result; +} + +int cp_lvprv_ask(g1_t v1[3], g2_t w2[4], g1_t p, g2_t q, bn_t c, bn_t r[3], g1_t u1[2], g2_t u2[2], g2_t v2[4]) { + int result = RLC_OK; + bn_t n; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + pc_get_ord(n); + bn_mod_inv(n, r[2], n); + g1_mul(v1[2], p, n); + for (int i = 0; i < 2; i++) { + /* Compute V1 = [r](A - Ui). */ + g1_sub(v1[i], p, u1[i]); + g1_mul(v1[i], v1[i], r[i]); + } + g2_mul(w2[0], q, r[2]); + g2_add(w2[2], w2[0], v2[2]); + g2_mul(w2[3], w2[0], c); + g2_add(w2[3], w2[3], v2[3]); + g2_copy(w2[0], v2[0]); + g2_copy(w2[1], v2[1]); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(n); + } + + return result; +} + +int cp_lvprv_ans(gt_t g[4], g1_t v1[3], g2_t w2[4]) { + int result = RLC_OK; + g1_t _p[2]; + g2_t _q[2]; + + g1_null(_p[0]); + g1_null(_p[1]); + g2_null(_q[0]); + g2_null(_q[1]); + + RLC_TRY { + g1_new(_p[0]); + g1_new(_p[1]); + g2_new(_q[0]); + g2_new(_q[1]); + + g1_copy(_p[0], v1[0]); + g1_copy(_p[1], v1[2]); + g2_copy(_q[0], w2[0]); + g2_copy(_q[1], w2[2]); + pc_map_sim(g[0], _p, _q, 2); + pc_map(g[1], v1[1], w2[1]); + pc_map(g[2], v1[2], w2[3]); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + g1_free(_p[0]); + g1_free(_p[1]); + g2_free(_q[0]); + g2_free(_q[1]); + } + return result; +} + +int cp_lvprv_ver(gt_t r, gt_t g[4], bn_t c, gt_t e[2]) { + int result = 1; + gt_t t; + + gt_null(t); + + RLC_TRY { + gt_new(t); + + result &= gt_is_valid(g[0]); + result &= gt_is_valid(g[1]); + + gt_mul(r, g[0], e[0]); + gt_exp(t, r, c); + gt_mul(t, t, g[1]); + gt_mul(t, t, e[1]); + + if (!result || gt_cmp(t, g[2]) != RLC_EQ) { + gt_set_unity(r); + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + gt_free(t); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_phpe.c b/contrib/relic/src/cp/relic_cp_phpe.c index ce1971b1f..c10e0f453 100644 --- a/contrib/relic/src/cp/relic_cp_phpe.c +++ b/contrib/relic/src/cp/relic_cp_phpe.c @@ -29,16 +29,7 @@ * @ingroup cp */ -#include - -#include "relic_core.h" -#include "relic_multi.h" -#include "relic_conf.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" +#include "relic.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_pok.c b/contrib/relic/src/cp/relic_cp_pok.c new file mode 100644 index 000000000..236408875 --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_pok.c @@ -0,0 +1,265 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of protocols for proof of knowledge of discrete logarithms. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +/* + * Source: "Proof Systems for General Statements about Discrete Logarithms" + * Authors: Jan Camenisc, Markus Stadler (1997) + */ + +int cp_pokdl_prv(bn_t c, bn_t r, ec_t y, bn_t x) { + bn_t n, v; + ec_t t; + int l, result = RLC_OK; + uint8_t *buf, bin[3 * (RLC_FC_BYTES + 1)] = { 0 }, h[RLC_MD_LEN]; + + bn_null(n); + bn_null(v); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(v); + ec_new(t); + + buf = bin; + ec_curve_get_ord(n); + ec_curve_get_gen(t); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y, 1); + ec_write_bin(buf, l, y, 1); + buf += l; + + bn_rand_mod(v, n); + ec_mul_gen(t, v); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + md_map(h, bin, sizeof(bin)); + bn_read_bin(c, h, RLC_MD_LEN); + bn_mod(c, c, n); + bn_mul(r, c, x); + bn_sub(r, v, r); + bn_mod(r, r, n); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v); + ec_free(t); + } + return result; +} + +int cp_pokdl_ver(bn_t c, bn_t r, ec_t y) { + bn_t n, v; + ec_t t; + int l, result = 0; + uint8_t *buf, bin[3 * (RLC_FC_BYTES + 1)] = { 0 }, h[RLC_MD_LEN]; + + bn_null(n); + bn_null(v); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(v); + ec_new(t); + + buf = bin; + ec_curve_get_ord(n); + ec_curve_get_gen(t); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y, 1); + ec_write_bin(buf, l, y, 1); + buf += l; + + /* Compute t' = [r]G + [c]Y. */ + ec_mul_sim_gen(t, r, y, c); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + md_map(h, bin, sizeof(bin)); + bn_read_bin(v, h, RLC_MD_LEN); + bn_mod(v, v, n); + if (bn_cmp(v, c) == RLC_EQ) { + result = 1; + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v); + ec_free(t); + } + return result; +} + +int cp_pokor_prv(bn_t c[2], bn_t r[2], ec_t y[2], bn_t x) { + bn_t n, v[2], z; + ec_t t; + int l, result = RLC_OK; + uint8_t *buf, bin[6 * (RLC_FC_BYTES + 1)] = { 0 }, h[RLC_MD_LEN]; + + bn_null(n); + bn_null(v[0]); + bn_null(v[1]); + bn_null(z); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(v[0]); + bn_new(v[1]); + bn_new(z); + ec_new(t); + + buf = bin; + ec_curve_get_ord(n); + bn_rand_mod(c[0], n); + + for (int i = 0; i < 2; i++) { + bn_rand_mod(v[i], n); + ec_curve_get_gen(t); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y[i], 1); + ec_write_bin(buf, l, y[i], 1); + buf += l; + + if (i == 0) { + /* T1 = [w]Y1 + [v1]G. */ + ec_mul_sim_gen(t, v[i], y[i], c[i]); + } else { + /* T2 = [v2]G. */ + ec_mul_gen(t, v[i]); + } + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + } + md_map(h, bin, sizeof(bin)); + bn_read_bin(z, h, RLC_MD_LEN); + bn_mod(z, z, n); + + bn_sub(c[1], z, c[0]); + bn_mod(c[1], c[1], n); + + bn_copy(r[0], v[0]); + bn_mul(r[1], c[1], x); + bn_sub(r[1], v[1], r[1]); + bn_mod(r[1], r[1], n); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v[0]); + bn_free(v[1]); + bn_free(z); + ec_free(t); + } + return result; +} + +int cp_pokor_ver(bn_t c[2], bn_t r[2], ec_t y[2]) { + bn_t n, v[2], z; + ec_t t; + int l, result = 0; + uint8_t *buf, bin[6 * (RLC_FC_BYTES + 1)] = { 0 }, h[RLC_MD_LEN]; + + bn_null(n); + bn_null(v[0]); + bn_null(v[1]); + bn_null(z); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(v[0]); + bn_new(v[1]); + bn_new(z); + ec_new(t); + + buf = bin; + ec_curve_get_ord(n); + + for (int i = 0; i < 2; i++) { + ec_curve_get_gen(t); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y[i], 1); + ec_write_bin(buf, l, y[i], 1); + buf += l; + + ec_mul_sim_gen(t, r[i], y[i], c[i]); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + } + md_map(h, bin, sizeof(bin)); + bn_read_bin(z, h, RLC_MD_LEN); + bn_mod(z, z, n); + + bn_sub(z, z, c[0]); + bn_sub(z, z, c[1]); + bn_mod(z, z, n); + + if (bn_is_zero(z)) { + result = 1; + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v[0]); + bn_free(v[1]); + bn_free(z); + ec_free(t); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_rabin.c b/contrib/relic/src/cp/relic_cp_rabin.c index f47eaa1d3..d945f7eef 100644 --- a/contrib/relic/src/cp/relic_cp_rabin.c +++ b/contrib/relic/src/cp/relic_cp_rabin.c @@ -29,15 +29,7 @@ * @ingroup cp */ -#include - -#include "relic_core.h" -#include "relic_conf.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" +#include "relic.h" /*============================================================================*/ /* Private definitions */ diff --git a/contrib/relic/src/cp/relic_cp_rsa.c b/contrib/relic/src/cp/relic_cp_rsa.c index 62749dbd8..e8e7a7ca9 100644 --- a/contrib/relic/src/cp/relic_cp_rsa.c +++ b/contrib/relic/src/cp/relic_cp_rsa.c @@ -29,16 +29,7 @@ * @ingroup cp */ -#include - -#include "relic_core.h" -#include "relic_conf.h" -#include "relic_rand.h" -#include "relic_bn.h" -#include "relic_util.h" -#include "relic_cp.h" -#include "relic_md.h" -#include "relic_multi.h" +#include "relic.h" /*============================================================================*/ /* Private definitions */ @@ -274,10 +265,8 @@ static int pad_pkcs1(bn_t m, int *p_len, int m_len, int k_len, int operation) { } while (pad == 0); bn_add_dig(m, m, pad); } - bn_lsh(m, m, 8); - bn_add_dig(m, m, 0); - /* Make room for the real message. */ - bn_lsh(m, m, m_len * 8); + /* Make room for the zero and real message. */ + bn_lsh(m, m, (m_len + 1) * 8); result = RLC_OK; break; case RSA_DEC: @@ -313,9 +302,8 @@ static int pad_pkcs1(bn_t m, int *p_len, int m_len, int k_len, int operation) { bn_lsh(m, m, 8); bn_add_dig(m, m, RSA_PAD); } - bn_lsh(m, m, 8); - bn_add_dig(m, m, 0); - bn_lsh(m, m, 8 * len); + /* Make room for the zero and hash id. */ + bn_lsh(m, m, 8 * (len + 1)); bn_read_bin(t, id, len); bn_add(m, m, t); /* Make room for the real message. */ @@ -333,10 +321,8 @@ static int pad_pkcs1(bn_t m, int *p_len, int m_len, int k_len, int operation) { bn_lsh(m, m, 8); bn_add_dig(m, m, RSA_PAD); } - bn_lsh(m, m, 8); - bn_add_dig(m, m, 0); - /* Make room for the real message. */ - bn_lsh(m, m, m_len * 8); + /* Make room for the zero and hash. */ + bn_lsh(m, m, 8 * (m_len + 1)); result = RLC_OK; break; case RSA_VER: @@ -356,19 +342,22 @@ static int pad_pkcs1(bn_t m, int *p_len, int m_len, int k_len, int operation) { } while (pad == RSA_PAD && m_len > 0); /* Remove padding and trailing zero. */ id = hash_id(MD_MAP, &len); - m_len -= len; - - bn_rsh(t, m, m_len * 8); - int r = 0; - for (int i = 0; i < len; i++) { - pad = (uint8_t)t->dp[0]; - r |= pad ^ id[len - i - 1]; - bn_rsh(t, t, 8); - } - *p_len = k_len - m_len; - bn_mod_2b(m, m, m_len * 8); - if (r == 0 && m_len > 0 && counter >= 8) { - result = RLC_OK; + bn_rsh(t, m, 8 * m_len); + bn_mod_2b(t, t, 8); + if (bn_is_zero(t)) { + m_len -= len; + bn_rsh(t, m, 8 * m_len); + int r = 0; + for (int i = 0; i < len; i++) { + pad = (uint8_t)t->dp[0]; + r |= pad ^ id[len - i - 1]; + bn_rsh(t, t, 8); + } + *p_len = k_len - m_len; + bn_mod_2b(m, m, m_len * 8); + if (r == 0 && m_len == RLC_MD_LEN && counter >= 8) { + result = RLC_OK; + } } } } @@ -390,9 +379,13 @@ static int pad_pkcs1(bn_t m, int *p_len, int m_len, int k_len, int operation) { } while (pad == RSA_PAD && m_len > 0); /* Remove padding and trailing zero. */ *p_len = k_len - m_len; - bn_mod_2b(m, m, m_len * 8); - if (m_len > 0 && counter >= 8) { - result = RLC_OK; + bn_rsh(t, m, 8 * m_len); + bn_mod_2b(t, t, 8); + if (bn_is_zero(t)) { + bn_mod_2b(m, m, m_len * 8); + if (m_len == RLC_MD_LEN && counter >= 8) { + result = RLC_OK; + } } } } diff --git a/contrib/relic/src/cp/relic_cp_smlers.c b/contrib/relic/src/cp/relic_cp_smlers.c new file mode 100644 index 000000000..6dbe0b1cb --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_smlers.c @@ -0,0 +1,187 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developsmlers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the vsmlersion 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or vsmlersion 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of extendable ring signatures. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int cp_smlers_sig(bn_t td, smlers_t p, uint8_t *msg, int len, bn_t sk, ec_t pk, + ec_t pp) { + ec_t g[2], y[2]; + int result = RLC_OK; + + ec_null(g[0]); + ec_null(g[1]); + ec_null(y[0]); + ec_null(y[1]); + + RLC_TRY { + ec_new(g[0]); + ec_new(g[1]); + ec_new(y[0]); + ec_new(y[1]); + + ec_curve_get_gen(g[0]); + ec_map(g[1], msg, len); + ec_mul(p->tau, g[1], sk); + + cp_ers_sig(td, p->sig, msg, len, sk, pk, pp); + + ec_copy(y[0], p->sig->h); + ec_copy(y[1], p->tau); + cp_sokor_sig(p->c, p->r, msg, len, y, g, sk, 0); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + ec_free(g[0]); + ec_free(g[1]); + ec_free(y[0]); + ec_free(y[1]); + } + return result; +} + +int cp_smlers_ver(bn_t td, smlers_t *s, int size, uint8_t *msg, int len, ec_t pp) { + bn_t n; + ec_t t, g[2], y[2]; + int flag = 0, result = 0; + + bn_null(n); + ec_null(t); + ec_null(g[0]); + ec_null(g[1]); + ec_null(y[0]); + ec_null(y[1]); + + RLC_TRY { + bn_new(n); + ec_new(t); + ec_new(g[0]); + ec_new(g[1]); + ec_new(y[0]); + ec_new(y[1]); + + ec_curve_get_ord(n); + ec_mul_gen(t, td); + ec_curve_get_gen(g[0]); + ec_map(g[1], msg, len); + + for (int i = 0; i < size; i++) { + ec_add(t, t, s[i]->sig->h); + } + if (ec_cmp(pp, t) == RLC_EQ) { + flag = 1; + for (int i = 0; i < size; i++) { + ec_copy(y[0], s[i]->sig->h); + ec_copy(y[1], s[i]->sig->pk); + flag &= cp_sokor_ver(s[i]->sig->c, s[i]->sig->r, msg, len, y, NULL); + ec_copy(y[1], s[i]->tau); + flag &= cp_sokor_ver(s[i]->c, s[i]->r, msg, len, y, g); + } + } + result = flag; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + ec_free(t); + ec_free(g[0]); + ec_free(g[1]); + ec_free(y[0]); + ec_free(y[1]); + } + return result; +} + +int cp_smlers_ext(bn_t td, smlers_t *p, int *size, uint8_t *msg, int len, ec_t pk, + ec_t pp) { + bn_t n, r; + ec_t g[2], y[2]; + int result = RLC_OK; + + bn_null(n); + bn_null(r); + ec_null(g[0]); + ec_null(g[1]); + ec_null(y[0]); + ec_null(y[1]); + + for (int i = 0; i < *size; i++) { + if (ec_cmp(pk, p[i]->sig->pk) == RLC_EQ) { + return RLC_ERR; + } + } + + RLC_TRY { + bn_new(n); + bn_new(r); + ec_new(g[0]); + ec_new(g[1]); + ec_new(y[0]); + ec_new(y[1]); + + ec_curve_get_ord(n); + bn_rand_mod(r, n); + bn_sub(td, td, r); + bn_mod(td, td, n); + ec_mul_gen(p[*size]->sig->h, r); + ec_curve_get_gen(g[0]); + ec_map(g[1], msg, len); + + ec_copy(p[*size]->sig->pk, pk); + ec_copy(y[0], p[*size]->sig->h); + ec_copy(y[1], p[*size]->sig->pk); + cp_sokor_sig(p[*size]->sig->c, p[*size]->sig->r, msg, len, y, NULL, r, 1); + ec_copy(p[*size]->tau, p[*size - 1]->tau); + ec_copy(y[1], p[*size]->tau); + cp_sokor_sig(p[*size]->c, p[*size]->r, msg, len, y, g, r, 1); + (*size)++; + result = RLC_OK; + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(r); + ec_free(g[0]); + ec_free(g[1]); + ec_free(y[0]); + ec_free(y[1]); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_sok.c b/contrib/relic/src/cp/relic_cp_sok.c new file mode 100644 index 000000000..0713910f0 --- /dev/null +++ b/contrib/relic/src/cp/relic_cp_sok.c @@ -0,0 +1,333 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of protocols for proof of knowledge of discrete logarithms. + * + * @ingroup cp + */ + +#include "relic.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +/* + * Source: "Efficient Group Signature for Large Groups" + * Authors: Jan Camenisch, Markus Stadler + */ + +int cp_sokdl_sig(bn_t c, bn_t s, uint8_t *msg, int len, ec_t y, bn_t x) { + bn_t n, r; + ec_t t; + uint8_t h[RLC_MD_LEN]; + uint8_t *buf, *m = RLC_ALLOCA(uint8_t, len + 3 * (RLC_FC_BYTES + 1)); + int l, result = RLC_OK; + + bn_null(n); + bn_null(r); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(r); + ec_new(t); + if (m == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + + buf = m; + ec_curve_get_ord(n); + ec_curve_get_gen(t); + memcpy(buf, msg, len); + buf += len; + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y, 1); + ec_write_bin(buf, l, y, 1); + buf += l; + + bn_rand_mod(r, n); + ec_mul_gen(t, r); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + + md_map(h, m, len + 3 * (RLC_FC_BYTES + 1)); + bn_read_bin(c, h, RLC_MD_LEN); + bn_mod(c, c, n); + + bn_mul(s, c, x); + bn_sub(s, r, s); + bn_mod(s, s, n); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(r); + ec_free(t); + RLC_FREE(m); + } + return result; +} + +int cp_sokdl_ver(bn_t c, bn_t s, uint8_t *msg, int len, ec_t y) { + bn_t n, v; + ec_t t; + uint8_t h[RLC_MD_LEN]; + uint8_t *buf, *m = RLC_ALLOCA(uint8_t, len + 3 * (RLC_FC_BYTES + 1)); + int l, result = 0; + + bn_null(n); + bn_null(v); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(v); + ec_new(t); + if (m == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + + buf = m; + ec_curve_get_ord(n); + ec_curve_get_gen(t); + memcpy(buf, msg, len); + buf += len; + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y, 1); + ec_write_bin(buf, l, y, 1); + buf += l; + + /* Compute t' = [r]G + [c]Y. */ + ec_mul_sim_gen(t, s, y, c); + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + + md_map(h, m, len + 3 * (RLC_FC_BYTES + 1)); + bn_read_bin(v, h, RLC_MD_LEN); + bn_mod(v, v, n); + + if (bn_cmp(v, c) == RLC_EQ) { + result = 1; + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v); + ec_free(t); + RLC_FREE(m); + } + return result; +} + +int cp_sokor_sig(bn_t c[2], bn_t s[2], uint8_t *msg, int len, ec_t y[2], + ec_t g[2], bn_t x, int first) { + bn_t n, v[2], z; + ec_t u, t[2]; + uint8_t h[RLC_MD_LEN]; + uint8_t *buf, *m = RLC_ALLOCA(uint8_t, len + 6 * (RLC_FC_BYTES + 1)); + int l, result = RLC_OK; + int one = 1 ^ first; + int zero = 0 ^ first; + + bn_null(n); + bn_null(v[0]); + bn_null(v[1]); + bn_null(z); + ec_null(u); + ec_null(t[0]); + ec_null(t[1]); + + RLC_TRY { + bn_new(n); + bn_new(v[0]); + bn_new(v[1]); + bn_new(z); + ec_new(u); + ec_new(t[0]); + ec_new(t[1]); + if (m == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + + buf = m; + ec_curve_get_ord(n); + bn_rand_mod(c[zero], n); + memcpy(buf, msg, len); + buf += len; + + bn_rand_mod(v[0], n); + bn_rand_mod(v[1], n); + if (first) { + if (g != NULL) { + ec_mul(t[0], g[0], v[0]); + ec_mul_sim(t[1], g[1], v[1], y[1], c[zero]); + } else { + ec_mul_gen(t[0], v[0]); + ec_mul_sim_gen(t[1], v[1], y[1], c[zero]); + } + } else { + if (g != NULL) { + /* T1 = [w]Y1 + [v1]G. */ + ec_mul_sim(t[0], g[0], v[0], y[0], c[zero]); + /* T2 = [v2]G. */ + ec_mul(t[1], g[1], v[1]); + } else { + /* T1 = [w]Y1 + [v1]G. */ + ec_mul_sim_gen(t[0], v[0], y[0], c[zero]); + /* T2 = [v2]G. */ + ec_mul_gen(t[1], v[1]); + } + } + + ec_curve_get_gen(u); + for (int i = 0; i < 2; i++) { + if (g != NULL) { + ec_copy(u, g[i]); + } + l = ec_size_bin(u, 1); + ec_write_bin(buf, l, u, 1); + buf += l; + l = ec_size_bin(y[i], 1); + ec_write_bin(buf, l, y[i], 1); + buf += l; + l = ec_size_bin(t[i], 1); + ec_write_bin(buf, l, t[i], 1); + buf += l; + } + md_map(h, m, len + 6 * (RLC_FC_BYTES + 1)); + bn_read_bin(z, h, RLC_MD_LEN); + bn_mod(z, z, n); + + bn_sub(c[one], z, c[zero]); + bn_mod(c[one], c[one], n); + + bn_copy(s[zero], v[zero]); + bn_mul(s[one], c[one], x); + bn_sub(s[one], v[one], s[one]); + bn_mod(s[one], s[one], n); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v[0]); + bn_free(v[1]); + bn_free(z); + ec_free(u); + ec_free(t[0]); + ec_free(t[1]); + RLC_FREE(m); + } + return result; +} + +int cp_sokor_ver(bn_t c[2], bn_t s[2], uint8_t *msg, int len, ec_t y[2], + ec_t g[2]) { + bn_t n, v[2], z; + ec_t t; + uint8_t h[RLC_MD_LEN]; + uint8_t *buf, *m = RLC_ALLOCA(uint8_t, len + 6 * (RLC_FC_BYTES + 1)); + int l, result = 0; + + bn_null(n); + bn_null(v[0]); + bn_null(v[1]); + bn_null(z); + ec_null(t); + + RLC_TRY { + bn_new(n); + bn_new(v[0]); + bn_new(v[1]); + bn_new(z); + ec_new(t); + if (m == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + + buf = m; + ec_curve_get_ord(n); + memcpy(buf, msg, len); + buf += len; + + for (int i = 0; i < 2; i++) { + if (g != NULL) { + ec_copy(t, g[i]); + } else { + ec_curve_get_gen(t); + } + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + l = ec_size_bin(y[i], 1); + ec_write_bin(buf, l, y[i], 1); + buf += l; + if (g != NULL) { + ec_mul_sim(t, g[i], s[i], y[i], c[i]); + } else { + ec_mul_sim_gen(t, s[i], y[i], c[i]); + } + l = ec_size_bin(t, 1); + ec_write_bin(buf, l, t, 1); + buf += l; + } + md_map(h, m, len + 6 * (RLC_FC_BYTES + 1)); + bn_read_bin(z, h, RLC_MD_LEN); + bn_mod(z, z, n); + + bn_sub(z, z, c[0]); + bn_sub(z, z, c[1]); + bn_mod(z, z, n); + + if (bn_is_zero(z)) { + result = 1; + } + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(v[0]); + bn_free(v[1]); + bn_free(z); + ec_free(t); + RLC_FREE(m); + } + return result; +} diff --git a/contrib/relic/src/cp/relic_cp_sokaka.c b/contrib/relic/src/cp/relic_cp_sokaka.c index 03ecd1bb8..303fab912 100644 --- a/contrib/relic/src/cp/relic_cp_sokaka.c +++ b/contrib/relic/src/cp/relic_cp_sokaka.c @@ -30,15 +30,7 @@ * @ingroup test */ -#include -#include -#include -#include -#include - #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/cp/relic_cp_vbnn.c b/contrib/relic/src/cp/relic_cp_vbnn.c index a07dac6bd..c904d0f85 100644 --- a/contrib/relic/src/cp/relic_cp_vbnn.c +++ b/contrib/relic/src/cp/relic_cp_vbnn.c @@ -33,8 +33,6 @@ */ #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ @@ -216,7 +214,7 @@ int cp_vbnn_ver(ec_t r, bn_t z, bn_t h, uint8_t *id, int id_len, if (buf == NULL) { RLC_THROW(ERR_NO_MEMORY); } - + /* get order of ECC group */ ec_curve_get_ord(n); diff --git a/contrib/relic/src/cp/relic_cp_zss.c b/contrib/relic/src/cp/relic_cp_zss.c index 9f16d967d..2e0e70920 100644 --- a/contrib/relic/src/cp/relic_cp_zss.c +++ b/contrib/relic/src/cp/relic_cp_zss.c @@ -31,8 +31,6 @@ */ #include "relic.h" -#include "relic_test.h" -#include "relic_bench.h" /*============================================================================*/ /* Public definitions */ diff --git a/contrib/relic/src/dv/relic_dv_util.c b/contrib/relic/src/dv/relic_dv_util.c index 9ecb043f1..d5329da35 100644 --- a/contrib/relic/src/dv/relic_dv_util.c +++ b/contrib/relic/src/dv/relic_dv_util.c @@ -109,7 +109,7 @@ int dv_cmp(const dig_t *a, const dig_t *b, int size) { } int dv_cmp_const(const dig_t *a, const dig_t *b, int size) { - int r = 0; + dig_t r = 0; for (int i = 0; i < size; i++) { r |= a[i] ^ b[i]; diff --git a/contrib/relic/src/eb/relic_eb_curve.c b/contrib/relic/src/eb/relic_eb_curve.c index 2fe6228e0..9d829d824 100644 --- a/contrib/relic/src/eb/relic_eb_curve.c +++ b/contrib/relic/src/eb/relic_eb_curve.c @@ -73,8 +73,8 @@ void eb_curve_init(void) { fb_zero(ctx->eb_g.x); fb_zero(ctx->eb_g.y); fb_zero(ctx->eb_g.z); - bn_init(&(ctx->eb_r), RLC_FB_DIGS); - bn_init(&(ctx->eb_h), RLC_FB_DIGS); + bn_make(&(ctx->eb_r), RLC_FB_DIGS); + bn_make(&(ctx->eb_h), RLC_FB_DIGS); } void eb_curve_clean(void) { diff --git a/contrib/relic/src/eb/relic_eb_mul.c b/contrib/relic/src/eb/relic_eb_mul.c index 1bab3c82d..cd3cdb02c 100644 --- a/contrib/relic/src/eb/relic_eb_mul.c +++ b/contrib/relic/src/eb/relic_eb_mul.c @@ -890,7 +890,7 @@ void eb_mul_rwnaf(eb_t r, const eb_t p, const bn_t k) { void eb_mul_halve(eb_t r, const eb_t p, const bn_t k) { int i, j, l, trc, cof; - int8_t naf[RLC_FB_BITS + 1] = { 0 }, *_k; + int8_t naf[RLC_FB_BITS + 1], *_k; eb_t q, s, t[1 << (EB_WIDTH - 2)]; bn_t n, m; fb_t u, v, w, z; @@ -937,9 +937,6 @@ void eb_mul_halve(eb_t r, const eb_t p, const bn_t k) { l = sizeof(naf); bn_rec_naf(naf, &l, m, EB_WIDTH); - for (i = l; i <= bn_bits(n); i++) { - naf[i] = 0; - } if (naf[bn_bits(n)] == 1) { eb_dbl(t[0], p); } diff --git a/contrib/relic/src/eb/relic_eb_mul_sim.c b/contrib/relic/src/eb/relic_eb_mul_sim.c index 947bb981d..31d878ea8 100644 --- a/contrib/relic/src/eb/relic_eb_mul_sim.c +++ b/contrib/relic/src/eb/relic_eb_mul_sim.c @@ -222,13 +222,6 @@ static void eb_mul_sim_plain(eb_t r, const eb_t p, const bn_t k, const eb_t q, bn_rec_naf(naf1, &l1, m, EB_WIDTH); l = RLC_MAX(l0, l1); - for (i = l0; i < l; i++) { - naf0[i] = 0; - } - for (i = l1; i < l; i++) { - naf1[i] = 0; - } - if (bn_sign(k) == RLC_NEG) { for (i = 0; i < l0; i++) { naf0[i] = -naf0[i]; diff --git a/contrib/relic/src/eb/relic_eb_norm.c b/contrib/relic/src/eb/relic_eb_norm.c index 7ddce052a..9f0e38681 100644 --- a/contrib/relic/src/eb/relic_eb_norm.c +++ b/contrib/relic/src/eb/relic_eb_norm.c @@ -135,10 +135,11 @@ void eb_norm_sim(eb_t *r, const eb_t *t, int n) { fb_copy(r[i]->z, a[i]); } } - +#if EB_ADD == PROJC || !defined(STRIP) for (int i = 0; i < n; i++) { eb_norm_imp(r[i], r[i], 1); } +#endif /* EB_ADD == PROJC */ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/eb/relic_eb_util.c b/contrib/relic/src/eb/relic_eb_util.c index 942366352..0671fbb0e 100644 --- a/contrib/relic/src/eb/relic_eb_util.c +++ b/contrib/relic/src/eb/relic_eb_util.c @@ -543,6 +543,11 @@ void eb_read_bin(eb_t a, const uint8_t *bin, int len) { return; } } + + if (!eb_on_curve(a)) { + RLC_THROW(ERR_NO_VALID); + return; + } } void eb_write_bin(uint8_t *bin, int len, const eb_t a, int pack) { @@ -550,12 +555,13 @@ void eb_write_bin(uint8_t *bin, int len, const eb_t a, int pack) { eb_null(t); + memset(bin, 0, len); + if (eb_is_infty(a)) { if (len < 1) { RLC_THROW(ERR_NO_BUFFER); return; } else { - bin[0] = 0; return; } } diff --git a/contrib/relic/src/ed/relic_ed_add.c b/contrib/relic/src/ed/relic_ed_add.c index 9e4fd2d17..2bfee3f50 100644 --- a/contrib/relic/src/ed/relic_ed_add.c +++ b/contrib/relic/src/ed/relic_ed_add.c @@ -281,7 +281,7 @@ void ed_add_extnd(ed_t r, const ed_t p, const ed_t q) { fp_mul(r->t, t2, r->z); fp_mul(r->z, t3, t4); - r->coord = PROJC; + r->coord = EXTND; } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT) } RLC_FINALLY { diff --git a/contrib/relic/src/ed/relic_ed_curve.c b/contrib/relic/src/ed/relic_ed_curve.c index 0c4153bc5..0e1550e89 100644 --- a/contrib/relic/src/ed/relic_ed_curve.c +++ b/contrib/relic/src/ed/relic_ed_curve.c @@ -40,8 +40,8 @@ void ed_curve_init(void) { } #endif ed_set_infty(&ctx->ed_g); - bn_init(&ctx->ed_r, RLC_FP_DIGS); - bn_init(&ctx->ed_h, RLC_FP_DIGS); + bn_make(&ctx->ed_r, RLC_FP_DIGS); + bn_make(&ctx->ed_h, RLC_FP_DIGS); } void ed_curve_clean(void) { diff --git a/contrib/relic/src/ed/relic_ed_dbl.c b/contrib/relic/src/ed/relic_ed_dbl.c index 4a41a6a50..e62ecfe53 100644 --- a/contrib/relic/src/ed/relic_ed_dbl.c +++ b/contrib/relic/src/ed/relic_ed_dbl.c @@ -184,6 +184,8 @@ void ed_dbl_extnd(ed_t r, const ed_t p) { // efd: dbl-2008-hwcd, rfc edition // 4M + 4S + 1D + 7add + r->coord = PROJC; + /* A = X^2, B = Y^2 */ fp_sqr(t0, p->x); fp_sqr(t1, p->y); @@ -213,11 +215,10 @@ void ed_dbl_extnd(ed_t r, const ed_t p) { if (r->coord != EXTND) { /* T = E * H */ fp_mul(r->t, t2, r->z); + r->coord = EXTND; } /* Z = F * G */ fp_mul(r->z, t3, t4); - - r->coord = PROJC; } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { diff --git a/contrib/relic/src/ed/relic_ed_mul.c b/contrib/relic/src/ed/relic_ed_mul.c index 09a17e7e0..725401590 100644 --- a/contrib/relic/src/ed/relic_ed_mul.c +++ b/contrib/relic/src/ed/relic_ed_mul.c @@ -406,27 +406,37 @@ void ed_mul_gen(ed_t r, const bn_t k) { } void ed_mul_dig(ed_t r, const ed_t p, dig_t k) { - int i, l; ed_t t; + bn_t _k; + int8_t u, naf[RLC_DIG + 1]; + int l; ed_null(t); + bn_null(_k); - if (k == 0) { + if (k == 0 || ed_is_infty(p)) { ed_set_infty(r); return; } RLC_TRY { ed_new(t); + bn_new(_k); - l = util_bits_dig(k); + bn_set_dig(_k, k); - ed_copy(t, p); + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _k, 2); - for (i = l - 2; i >= 0; i--) { + ed_set_infty(t); + for (int i = l - 1; i >= 0; i--) { ed_dbl(t, t); - if (k & ((dig_t)1 << i)) { + + u = naf[i]; + if (u > 0) { ed_add(t, t, p); + } else if (u < 0) { + ed_sub(t, t, p); } } @@ -437,5 +447,6 @@ void ed_mul_dig(ed_t r, const ed_t p, dig_t k) { } RLC_FINALLY { ed_free(t); + bn_free(_k); } } diff --git a/contrib/relic/src/ed/relic_ed_mul_sim.c b/contrib/relic/src/ed/relic_ed_mul_sim.c index acbc8e14c..b9b70410e 100644 --- a/contrib/relic/src/ed/relic_ed_mul_sim.c +++ b/contrib/relic/src/ed/relic_ed_mul_sim.c @@ -88,13 +88,6 @@ static void ed_mul_sim_plain(ed_t r, const ed_t p, const bn_t k, const ed_t q, bn_rec_naf(naf1, &l1, m, ED_WIDTH); l = RLC_MAX(l0, l1); - for (i = l0; i < l; i++) { - naf0[i] = 0; - } - for (i = l1; i < l; i++) { - naf1[i] = 0; - } - if (bn_sign(k) == RLC_NEG) { for (i = 0; i < l0; i++) { naf0[i] = -naf0[i]; diff --git a/contrib/relic/src/ed/relic_ed_norm.c b/contrib/relic/src/ed/relic_ed_norm.c index cc06c42aa..8979df0cc 100644 --- a/contrib/relic/src/ed/relic_ed_norm.c +++ b/contrib/relic/src/ed/relic_ed_norm.c @@ -37,8 +37,6 @@ #if ED_ADD == PROJC || ED_ADD == EXTND || !defined(STRIP) -#include "assert.h" - /** * Normalizes a point represented in projective coordinates. * @@ -111,9 +109,11 @@ void ed_norm_sim(ed_t *r, const ed_t *t, int n) { } } +#if ED_ADD == PROJC || ED_ADD == EXTND || !defined(STRIP) for (int i = 0; i < n; i++) { ed_norm_imp(r[i], r[i], 1); } +#endif /* ED_ADD != BASIC*/ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/ed/relic_ed_util.c b/contrib/relic/src/ed/relic_ed_util.c index c43fbaf41..55c3d68d5 100644 --- a/contrib/relic/src/ed/relic_ed_util.c +++ b/contrib/relic/src/ed/relic_ed_util.c @@ -122,12 +122,16 @@ void ed_blind(ed_t r, const ed_t p) { RLC_TRY { fp_new(rand); - fp_rand(rand); +#if ED_ADD == BASIC + (void)rand; + ed_copy(r, p); +#elif ED_ADD == PROJC || ED_ADD == EXTND fp_mul(r->x, p->x, rand); fp_mul(r->y, p->y, rand); fp_mul(r->z, p->z, rand); r->coord = PROJC; +#endif #if ED_ADD == EXTND fp_mul(r->t, p->t, rand); #endif @@ -287,6 +291,10 @@ void ed_read_bin(ed_t a, const uint8_t *bin, int len) { fp_mul(a->y, a->y, a->z); fp_sqr(a->z, a->z); #endif + + if (!ed_on_curve(a)) { + RLC_THROW(ERR_NO_VALID); + } } void ed_write_bin(uint8_t *bin, int len, const ed_t a, int pack) { @@ -294,12 +302,13 @@ void ed_write_bin(uint8_t *bin, int len, const ed_t a, int pack) { ed_null(t); + memset(bin, 0, len); + if (ed_is_infty(a)) { if (len < 1) { RLC_THROW(ERR_NO_BUFFER); return; } else { - bin[0] = 0; return; } } @@ -310,7 +319,7 @@ void ed_write_bin(uint8_t *bin, int len, const ed_t a, int pack) { ed_norm(t, a); if (pack) { - if (len != RLC_FP_BYTES + 1) { + if (len < RLC_FP_BYTES + 1) { RLC_THROW(ERR_NO_BUFFER); } else { ed_pck(t, t); @@ -318,7 +327,7 @@ void ed_write_bin(uint8_t *bin, int len, const ed_t a, int pack) { fp_write_bin(bin + 1, RLC_FP_BYTES, t->y); } } else { - if (len != 2 * RLC_FP_BYTES + 1) { + if (len < 2 * RLC_FP_BYTES + 1) { RLC_THROW(ERR_NO_BUFFER); } else { bin[0] = 4; @@ -326,8 +335,7 @@ void ed_write_bin(uint8_t *bin, int len, const ed_t a, int pack) { fp_write_bin(bin + RLC_FP_BYTES + 1, RLC_FP_BYTES, t->x); } } - } - RLC_CATCH_ANY { + } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { diff --git a/contrib/relic/src/ep/relic_ep_curve.c b/contrib/relic/src/ep/relic_ep_curve.c index b4e21c577..f4aa0f329 100644 --- a/contrib/relic/src/ep/relic_ep_curve.c +++ b/contrib/relic/src/ep/relic_ep_curve.c @@ -209,12 +209,12 @@ void ep_curve_init(void) { } #endif ep_set_infty(&ctx->ep_g); - bn_init(&ctx->ep_r, RLC_FP_DIGS); - bn_init(&ctx->ep_h, RLC_FP_DIGS); + bn_make(&ctx->ep_r, RLC_FP_DIGS); + bn_make(&ctx->ep_h, RLC_FP_DIGS); #if defined(EP_ENDOM) && (EP_MUL == LWNAF || EP_FIX == COMBS || EP_FIX == LWNAF || !defined(STRIP)) for (int i = 0; i < 3; i++) { - bn_init(&(ctx->ep_v1[i]), RLC_FP_DIGS); - bn_init(&(ctx->ep_v2[i]), RLC_FP_DIGS); + bn_make(&(ctx->ep_v1[i]), RLC_FP_DIGS); + bn_make(&(ctx->ep_v2[i]), RLC_FP_DIGS); } #endif } diff --git a/contrib/relic/src/ep/relic_ep_dbl.c b/contrib/relic/src/ep/relic_ep_dbl.c index 66369fdb2..1a160d02c 100644 --- a/contrib/relic/src/ep/relic_ep_dbl.c +++ b/contrib/relic/src/ep/relic_ep_dbl.c @@ -513,10 +513,6 @@ void ep_dbl_projc(ep_t r, const ep_t p) { return; } - if (fp_is_zero(p->x)) { - ep_set_infty(r); - return; - } ep_dbl_projc_imp(r, p); } @@ -530,10 +526,6 @@ void ep_dbl_jacob(ep_t r, const ep_t p) { return; } - if (fp_is_zero(p->x)) { - ep_set_infty(r); - return; - } ep_dbl_jacob_imp(r, p); } diff --git a/contrib/relic/src/ep/relic_ep_map.c b/contrib/relic/src/ep/relic_ep_map.c index a2fa26b8b..10c2c57ad 100644 --- a/contrib/relic/src/ep/relic_ep_map.c +++ b/contrib/relic/src/ep/relic_ep_map.c @@ -49,27 +49,23 @@ * @param[in] deg - the degree of the polynomial. */ TMPL_MAP_HORNER(fp, fp_st) - /** * Generic isogeny map evaluation for use with SSWU map. */ -TMPL_MAP_ISOGENY_MAP(ep, fp, iso) + TMPL_MAP_ISOGENY_MAP(ep, fp, iso) #endif /* EP_CTMAP */ - /** * Simplified SWU mapping from Section 4 of * "Fast and simple constant-time hashing to the BLS12-381 Elliptic Curve" */ #define EP_MAP_COPY_COND(O, I, C) dv_copy_cond(O, I, RLC_FP_DIGS, C) -TMPL_MAP_SSWU(ep, fp, dig_t, EP_MAP_COPY_COND) - + TMPL_MAP_SSWU(ep, fp, dig_t, EP_MAP_COPY_COND) /** * Shallue--van de Woestijne map, based on the definition from * draft-irtf-cfrg-hash-to-curve-06, Section 6.6.1 */ TMPL_MAP_SVDW(ep, fp, dig_t, EP_MAP_COPY_COND) #undef EP_MAP_COPY_COND - /* caution: this function overwrites k, which it uses as an auxiliary variable */ static inline int fp_sgn0(const fp_t t, bn_t k) { fp_prime_back(k, t); @@ -80,51 +76,50 @@ static inline int fp_sgn0(const fp_t t, bn_t k) { /* Public definitions */ /*============================================================================*/ -void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst_len) { +void ep_map_from_field(ep_t p, const uint8_t *uniform_bytes, int len) { bn_t k; fp_t t; ep_t q; int neg; /* enough space for two field elements plus extra bytes for uniformity */ const int len_per_elm = (FP_PRIME + ep_param_level() + 7) / 8; - uint8_t *pseudo_random_bytes = RLC_ALLOCA(uint8_t, 2 * len_per_elm); bn_null(k); fp_null(t); ep_null(q); RLC_TRY { + if (len != 2 * len_per_elm) { + RLC_THROW(ERR_NO_VALID); + } + bn_new(k); fp_new(t); ep_new(q); /* figure out which hash function to use */ - const int abNeq0 = (ep_curve_opt_a() != RLC_ZERO) && (ep_curve_opt_b() != RLC_ZERO); - void (*const map_fn)(ep_t, fp_t) = (ep_curve_is_ctmap() || abNeq0) ? ep_map_sswu : ep_map_svdw; - - /* for hash_to_field, need to hash to a pseudorandom string */ - /* XXX(rsw) the below assumes that we want to use MD_MAP for hashing. - * Consider making the hash function a per-curve option! - */ - md_xmd(pseudo_random_bytes, 2 * len_per_elm, msg, len, dst, dst_len); - -#define EP_MAP_CONVERT_BYTES(IDX) \ - do { \ - bn_read_bin(k, pseudo_random_bytes + IDX * len_per_elm, len_per_elm); \ - fp_prime_conv(t, k); \ - } while (0) - -#define EP_MAP_APPLY_MAP(PT) \ - do { \ - /* check sign of t */ \ - neg = fp_sgn0(t, k); \ - /* convert */ \ - map_fn(PT, t); \ - /* compare sign of y and sign of t; fix if necessary */ \ - neg = neg != fp_sgn0(PT->y, k); \ - fp_neg(t, PT->y); \ - dv_copy_cond(PT->y, t, RLC_FP_DIGS, neg); \ - } while (0) + const int abNeq0 = (ep_curve_opt_a() != RLC_ZERO) && + (ep_curve_opt_b() != RLC_ZERO); + void (*const map_fn)(ep_t, fp_t) =(ep_curve_is_ctmap() || + abNeq0) ? ep_map_sswu : ep_map_svdw; + +#define EP_MAP_CONVERT_BYTES(IDX) \ + do { \ + bn_read_bin(k, uniform_bytes + IDX * len_per_elm, len_per_elm); \ + fp_prime_conv(t, k); \ + } while (0) + +#define EP_MAP_APPLY_MAP(PT) \ + do { \ + /* check sign of t */ \ + neg = fp_sgn0(t, k); \ + /* convert */ \ + map_fn(PT, t); \ + /* compare sign of y and sign of t; fix if necessary */ \ + neg = neg != fp_sgn0(PT->y, k); \ + fp_neg(t, PT->y); \ + dv_copy_cond(PT->y, t, RLC_FP_DIGS, neg); \ + } while (0) /* first map invocation */ EP_MAP_CONVERT_BYTES(0); @@ -152,6 +147,7 @@ void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst /* h = 1 */ break; case EP_B12: + case EP_B24: /* multiply by 1-x (x the BLS parameter) to get the correct group. */ /* XXX(rsw) is this guaranteed to work? It could fail if one * of the prime-squared subgroups is cyclic, but @@ -183,6 +179,28 @@ void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst bn_free(k); fp_free(t); ep_free(q); + } +} + +void ep_map_dst(ep_t p, const uint8_t *msg, int len, const uint8_t *dst, + int dst_len) { + + /* enough space for two field elements plus extra bytes for uniformity */ + const int len_per_elm = (FP_PRIME + ep_param_level() + 7) / 8; + uint8_t *pseudo_random_bytes = RLC_ALLOCA(uint8_t, 2 * len_per_elm); + + RLC_TRY { + /* for hash_to_field, need to hash to a pseudorandom string */ + /* XXX(rsw) the below assumes that we want to use MD_MAP for hashing. + * Consider making the hash function a per-curve option! + */ + md_xmd(pseudo_random_bytes, 2 * len_per_elm, msg, len, dst, dst_len); + ep_map_from_field(p, pseudo_random_bytes, 2 * len_per_elm); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { RLC_FREE(pseudo_random_bytes); } } diff --git a/contrib/relic/src/ep/relic_ep_mul.c b/contrib/relic/src/ep/relic_ep_mul.c index ff64143b6..d73353c3b 100644 --- a/contrib/relic/src/ep/relic_ep_mul.c +++ b/contrib/relic/src/ep/relic_ep_mul.c @@ -72,11 +72,7 @@ static void ep_mul_glv_imp(ep_t r, const ep_t p, const bn_t k) { ep_curve_get_v1(v1); ep_curve_get_v2(v2); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - + bn_mod(_k, k, n); bn_rec_glv(k0, k1, _k, n, (const bn_t *)v1, (const bn_t *)v2); s0 = bn_sign(k0); s1 = bn_sign(k1); @@ -97,10 +93,6 @@ static void ep_mul_glv_imp(ep_t r, const ep_t p, const bn_t k) { l = RLC_MAX(l0, l1); t0 = naf0 + l - 1; t1 = naf1 + l - 1; - for (i = l0; i < l; i++) - naf0[i] = 0; - for (i = l1; i < l; i++) - naf1[i] = 0; ep_set_infty(r); for (i = l - 1; i >= 0; i--, t0--, t1--) { @@ -180,10 +172,7 @@ static void ep_mul_naf_imp(ep_t r, const ep_t p, const bn_t k) { } ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } + bn_mod(_k, k, n); /* Compute the precomputation table. */ ep_tab(t, p, EP_WIDTH); @@ -235,11 +224,6 @@ static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { bn_t n, _k, k0, k1, v1[3], v2[3]; ep_t q, t[1 << (EP_WIDTH - 2)], u, v, w; - if (bn_is_zero(k)) { - ep_set_infty(r); - return; - } - bn_null(n); bn_null(_k); bn_null(k0); @@ -274,10 +258,8 @@ static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { ep_curve_get_v1(v1); ep_curve_get_v2(v2); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } + bn_abs(_k, k); + bn_mod(_k, _k, n); bn_rec_glv(k0, k1, _k, n, (const bn_t *)v1, (const bn_t *)v2); s0 = bn_sign(k0); @@ -358,7 +340,7 @@ static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { /* Convert r to affine coordinates. */ ep_norm(r, r); ep_neg(u, r); - dv_copy_cond(r->y, u->y, RLC_FP_DIGS, bn_sign(_k) == RLC_NEG); + dv_copy_cond(r->y, u->y, RLC_FP_DIGS, bn_sign(k) == RLC_NEG); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -417,7 +399,7 @@ static void ep_mul_reg_imp(ep_t r, const ep_t p, const bn_t k) { /* Make a copy of the scalar for processing. */ bn_abs(_k, k); - _k->dp[0] |= bn_is_even(_k); + _k->dp[0] |= 1; /* Compute the regular w-NAF representation of k. */ l = RLC_CEIL(n, EP_WIDTH - 1) + 1; @@ -481,8 +463,6 @@ static void ep_mul_reg_imp(ep_t r, const ep_t p, const bn_t k) { /* Public definitions */ /*============================================================================*/ -#if EP_MUL == BASIC || !defined(STRIP) - void ep_mul_basic(ep_t r, const ep_t p, const bn_t k) { ep_t t; @@ -517,8 +497,6 @@ void ep_mul_basic(ep_t r, const ep_t p, const bn_t k) { } } -#endif - #if EP_MUL == SLIDE || !defined(STRIP) void ep_mul_slide(ep_t r, const ep_t p, const bn_t k) { @@ -553,10 +531,7 @@ void ep_mul_slide(ep_t r, const ep_t p, const bn_t k) { #endif ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } + bn_mod(_k, k, n); /* Create table. */ for (i = 1; i < (1 << (EP_WIDTH - 1)); i++) { @@ -629,11 +604,7 @@ void ep_mul_monty(ep_t r, const ep_t p, const bn_t k) { ep_curve_get_ord(n); bits = bn_bits(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - + bn_mod(_k, k, n); bn_abs(l, _k); bn_add(l, l, n); bn_add(n, l, n); @@ -750,8 +721,12 @@ void ep_mul_gen(ep_t r, const bn_t k) { void ep_mul_dig(ep_t r, const ep_t p, dig_t k) { ep_t t; + bn_t _k; + int8_t u, naf[RLC_DIG + 1]; + int l; ep_null(t); + bn_null(_k); if (k == 0 || ep_is_infty(p)) { ep_set_infty(r); @@ -760,12 +735,22 @@ void ep_mul_dig(ep_t r, const ep_t p, dig_t k) { RLC_TRY { ep_new(t); + bn_new(_k); - ep_copy(t, p); - for (int i = util_bits_dig(k) - 2; i >= 0; i--) { + bn_set_dig(_k, k); + + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _k, 2); + + ep_set_infty(t); + for (int i = l - 1; i >= 0; i--) { ep_dbl(t, t); - if (k & ((dig_t)1 << i)) { + + u = naf[i]; + if (u > 0) { ep_add(t, t, p); + } else if (u < 0) { + ep_sub(t, t, p); } } @@ -776,5 +761,6 @@ void ep_mul_dig(ep_t r, const ep_t p, dig_t k) { } RLC_FINALLY { ep_free(t); + bn_free(_k); } } diff --git a/contrib/relic/src/ep/relic_ep_mul_fix.c b/contrib/relic/src/ep/relic_ep_mul_fix.c index a4e6589bf..913c392d7 100644 --- a/contrib/relic/src/ep/relic_ep_mul_fix.c +++ b/contrib/relic/src/ep/relic_ep_mul_fix.c @@ -121,11 +121,7 @@ static void ep_mul_combs_endom(ep_t r, const ep_t *t, const bn_t k) { ep_curve_get_v2(v2); l = RLC_CEIL(bn_bits(n), (2 * EP_DEPTH)); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - + bn_mod(_k, k, n); bn_rec_glv(k0, k1, _k, n, (const bn_t *)v1, (const bn_t *)v2); s0 = bn_sign(k0); s1 = bn_sign(k1); @@ -223,11 +219,7 @@ static void ep_mul_combs_plain(ep_t r, const ep_t *t, const bn_t k) { ep_curve_get_ord(n); l = RLC_CEIL(bn_bits(n), EP_DEPTH); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - + bn_mod(_k, k, n); n0 = bn_bits(_k); p0 = (EP_DEPTH) * l - 1; @@ -321,10 +313,7 @@ void ep_mul_fix_basic(ep_t r, const ep_t *t, const bn_t k) { bn_new(_k); ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } + bn_mod(_k, k, n); ep_set_infty(r); for (int i = 0; i < bn_bits(_k); i++) { @@ -480,11 +469,7 @@ void ep_mul_fix_combd(ep_t r, const ep_t *t, const bn_t k) { d = RLC_CEIL(bn_bits(n), EP_DEPTH); e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - + bn_mod(_k, k, n); ep_set_infty(r); n0 = bn_bits(_k); @@ -551,11 +536,7 @@ void ep_mul_fix_lwnaf(ep_t r, const ep_t *t, const bn_t k) { bn_new(_k); ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - + bn_mod(_k, k, n); ep_mul_fix_plain(r, t, _k); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -564,4 +545,5 @@ void ep_mul_fix_lwnaf(ep_t r, const ep_t *t, const bn_t k) { bn_free(_k); } } + #endif diff --git a/contrib/relic/src/ep/relic_ep_mul_sim.c b/contrib/relic/src/ep/relic_ep_mul_sim.c index f04de0e82..68e503eb7 100644 --- a/contrib/relic/src/ep/relic_ep_mul_sim.c +++ b/contrib/relic/src/ep/relic_ep_mul_sim.c @@ -139,18 +139,6 @@ static void ep_mul_sim_endom(ep_t r, const ep_t p, const bn_t k, const ep_t q, t1 = naf1 + l - 1; t2 = naf2 + l - 1; t3 = naf3 + l - 1; - for (i = l0; i < l; i++) { - naf0[i] = 0; - } - for (i = l1; i < l; i++) { - naf1[i] = 0; - } - for (i = l2; i < l; i++) { - naf2[i] = 0; - } - for (i = l3; i < l; i++) { - naf3[i] = 0; - } if (bn_sign(k) == RLC_NEG) { for (i = 0; i < l0; i++) { @@ -265,6 +253,221 @@ static void ep_mul_sim_endom(ep_t r, const ep_t p, const bn_t k, const ep_t q, } } +/** + * Multiplies and adds multiple elliptic curve points simultaneously. + * Computes R = \Sum_i=0..n [k_i]P_i. + * + * @param[out] r - the result. + * @param[out] p - the elements to multiply. + * @param[out] k - the integer scalars. + * @param[out] n - the number of elements to multiply. + */ +void ep_mul_sim_lot_endom(ep_t r, const ep_t p[], const bn_t k[], int n) { + const int len = RLC_FP_BITS + 1; + int i, j, m, l, _l[2], sk; + bn_t _k[2], q, v1[3], v2[3]; + int8_t ptr, *naf = RLC_ALLOCA(int8_t, 2 * n * len); + + bn_null(q); + + if (n <= 10) { + ep_t *_p = RLC_ALLOCA(ep_t, 2 * n); + + RLC_TRY { + if (naf == NULL || _p == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + bn_new(q); + for (j = 0; j < 2; j++) { + bn_null(_k[j]); + bn_new(_k[j]); + } + for (i = 0; i < n; i++) { + ep_null(_p[i]); + ep_new(_p[i]); + } + + for (i = 0; i < 3; i++) { + bn_null(v1[i]); + bn_null(v2[i]); + bn_new(v1[i]); + bn_new(v2[i]); + } + + l = 0; + ep_curve_get_ord(q); + ep_curve_get_v1(v1); + ep_curve_get_v2(v2); + for (i = 0; i < n; i++) { + ep_norm(_p[2*i], p[i]); + ep_psi(_p[2*i + 1], _p[2*i]); + bn_mod(_k[0], k[i], q); + sk = bn_sign(_k[0]); + bn_rec_glv(_k[0], _k[1], _k[0], q, (const bn_t *)v1, (const bn_t *)v2); + if (sk == RLC_NEG) { + bn_neg(_k[0], _k[0]); + bn_neg(_k[1], _k[1]); + } + for (j = 0; j < 2; j++) { + _l[j] = len; + bn_rec_naf(&naf[(2*i + j)*len], &_l[j], _k[j], 2); + if (bn_sign(_k[j]) == RLC_NEG) { + ep_neg(_p[2*i + j], _p[2*i + j]); + } + l = RLC_MAX(l, _l[j]); + } + } + + ep_set_infty(r); + for (i = l - 1; i >= 0; i--) { + ep_dbl(r, r); + for (j = 0; j < n; j++) { + for (m = 0; m < 2; m++) { + if (naf[(2*j + m)*len + i] > 0) { + ep_add(r, r, _p[2*j + m]); + } + if (naf[(2*j + m)*len + i] < 0) { + ep_sub(r, r, _p[2*j + m]); + } + } + } + } + ep_norm(r, r); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(q); + bn_free(_k[0]); + bn_free(_k[1]); + for (i = 0; i < n; i++) { + ep_free(_p[i]); + } + RLC_FREE(_p); + RLC_FREE(naf); + for (i = 0; i < 3; i++) { + bn_free(v1[i]); + bn_free(v2[i]); + } + } + } else { + const int w = RLC_MAX(2, util_bits_dig(n) - 2), c = (1 << (w - 2)); + ep_t s, t, u, v, *_p = RLC_ALLOCA(ep_t, 2 * c); + + ep_null(s); + ep_null(t); + ep_null(u); + ep_null(v); + + RLC_TRY { + if (naf == NULL || _p == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + bn_new(q); + ep_new(s); + ep_new(t); + ep_new(u); + ep_new(v); + for (i = 0; i < 2; i++) { + bn_null(_k[i]); + bn_new(_k[i]); + for (j = 0; j < c; j++) { + ep_null(_p[i*c + j]); + ep_new(_p[i*c + j]); + ep_set_infty(_p[i*c + j]); + } + } + for (i = 0; i < 3; i++) { + bn_null(v1[i]); + bn_null(v2[i]); + bn_new(v1[i]); + bn_new(v2[i]); + } + + l = 0; + ep_curve_get_ord(q); + ep_curve_get_v1(v1); + ep_curve_get_v2(v2); + for (i = 0; i < n; i++) { + bn_mod(_k[0], k[i], q); + sk = bn_sign(_k[0]); + bn_rec_glv(_k[0], _k[1], _k[0], q, (const bn_t *)v1, (const bn_t *)v2); + if (sk == RLC_NEG) { + bn_neg(_k[0], _k[0]); + bn_neg(_k[1], _k[1]); + } + for (j = 0; j < 2; j++) { + _l[j] = len; + bn_rec_naf(&naf[(2*i + j)*len], &_l[j], _k[j], w); + if (bn_sign(_k[j]) == RLC_NEG) { + for (m = 0; m < _l[j]; m++) { + naf[(2*i + j)*len + m] = -naf[(2*i + j)*len + m]; + } + } + l = RLC_MAX(l, _l[j]); + } + } + + ep_set_infty(s); + for (i = l - 1; i >= 0; i--) { + for (j = 0; j < n; j++) { + for (m = 0; m < 2; m++) { + ptr = naf[(2*j + m)*len + i]; + if (ptr != 0) { + ep_copy(t, p[j]); + if (ptr < 0) { + ptr = -ptr; + ep_neg(t, t); + } + ep_add(_p[m*c + (ptr >> 1)], _p[m*c + (ptr >> 1)], t); + } + } + } + + ep_set_infty(t); + for (m = 1; m >= 0; m--) { + ep_psi(t, t); + ep_set_infty(u); + ep_set_infty(v); + for (j = c - 1; j >= 0; j--) { + ep_add(u, u, _p[m*c + j]); + if (j == 0) { + ep_dbl(v, v); + } + ep_add(v, v, u); + ep_set_infty(_p[m*c + j]); + } + ep_add(t, t, v); + } + ep_dbl(s, s); + ep_add(s, s, t); + } + + /* Convert r to affine coordinates. */ + ep_norm(r, s); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(q); + ep_free(s); + ep_free(t); + ep_free(u); + ep_free(v); + for (i = 0; i < 2; i++) { + bn_free(_k[i]); + for (j = 0; j < c; j++) { + ep_free(_p[i*c + j]); + } + } + RLC_FREE(_p); + RLC_FREE(naf); + for (i = 0; i < 3; i++) { + bn_free(v1[i]); + bn_free(v2[i]); + } + } + } +} + #endif /* EP_ENDOM */ #if defined(EP_PLAIN) || defined(EP_SUPER) @@ -319,13 +522,6 @@ static void ep_mul_sim_plain(ep_t r, const ep_t p, const bn_t k, const ep_t q, bn_rec_naf(naf1, &l1, m, EP_WIDTH); l = RLC_MAX(l0, l1); - for (i = l0; i < l; i++) { - naf0[i] = 0; - } - for (i = l1; i < l; i++) { - naf1[i] = 0; - } - if (bn_sign(k) == RLC_NEG) { for (i = 0; i < l0; i++) { naf0[i] = -naf0[i]; @@ -377,6 +573,77 @@ static void ep_mul_sim_plain(ep_t r, const ep_t p, const bn_t k, const ep_t q, } } +/** + * Multiplies and adds multiple elliptic curve points simultaneously. + * Computes R = \Sum_i=0..n [k_i]P_i. + * + * @param[out] r - the result. + * @param[out] p - the elements to multiply. + * @param[out] k - the integer scalars. + * @param[out] n - the number of elements to multiply. + */ +void ep_mul_sim_lot_plain(ep_t r, const ep_t p[], const bn_t k[], int n) { + int i, j, l, *_l = RLC_ALLOCA(int, n); + ep_t *_p = RLC_ALLOCA(ep_t, n); + int8_t *naf = NULL; + + RLC_TRY { + l = 0; + for (i = 0; i < n; i++) { + l = RLC_MAX(l, bn_bits(k[i]) + 1); + } + naf = RLC_ALLOCA(int8_t, n * l); + if (naf == NULL || _p == NULL || _l == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + + for (i = 0; i < n; i++) { + ep_null(_p[i]); + ep_new(_p[i]); + } + + for (i = 0; i < n; i++) { + _l[i] = l; + ep_norm(_p[i], p[i]); + bn_rec_naf(&naf[i*l], &_l[i], k[i], 2); + if (bn_sign(k[i]) == RLC_NEG) { + ep_neg(_p[i], _p[i]); + } + } + + for (i = 0; i < n; i++) { + for (j = _l[i]; j < l; j++) { + naf[i*l + j] = 0; + } + } + + ep_set_infty(r); + for (i = l - 1; i >= 0; i--) { + ep_dbl(r, r); + for (j = 0; j < n; j++) { + if (naf[j*l + i] > 0) { + ep_add(r, r, _p[j]); + } + if (naf[j*l + i] < 0) { + ep_sub(r, r, _p[j]); + } + } + } + + /* Convert r to affine coordinates. */ + ep_norm(r, r); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + for (i = 0; i < n; i++) { + ep_free(_p[i]); + } + RLC_FREE(_l); + RLC_FREE(_p); + RLC_FREE(naf); + } +} + #endif /* EP_PLAIN || EP_SUPER */ #endif /* EP_SIM == INTER */ @@ -449,14 +716,8 @@ void ep_mul_sim_trick(ep_t r, const ep_t p, const bn_t k, const ep_t q, } ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - bn_copy(_m, m); - if (bn_cmp_abs(_m, n) == RLC_GT) { - bn_mod(_m, _m, n); - } + bn_mod(_k, k, n); + bn_mod(_m, m, n); ep_set_infty(t0[0]); ep_copy(t0[1], p); @@ -549,14 +810,8 @@ void ep_mul_sim_inter(ep_t r, const ep_t p, const bn_t k, const ep_t q, /* Handle this here to reduce complexity of static functions. */ ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - bn_copy(_m, m); - if (bn_cmp_abs(_m, n) == RLC_GT) { - bn_mod(_m, _m, n); - } + bn_mod(_k, k, n); + bn_mod(_m, m, n); #if defined(EP_ENDOM) if (ep_curve_is_endom()) { @@ -615,14 +870,8 @@ void ep_mul_sim_joint(ep_t r, const ep_t p, const bn_t k, const ep_t q, } ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - bn_copy(_m, m); - if (bn_cmp_abs(_m, n) == RLC_GT) { - bn_mod(_m, _m, n); - } + bn_mod(_k, k, n); + bn_mod(_m, m, n); ep_set_infty(t[0]); ep_copy(t[1], q); @@ -707,14 +956,8 @@ void ep_mul_sim_gen(ep_t r, const bn_t k, const ep_t q, const bn_t m) { ep_curve_get_gen(g); ep_curve_get_ord(n); - bn_copy(_k, k); - if (bn_cmp_abs(_k, n) == RLC_GT) { - bn_mod(_k, _k, n); - } - bn_copy(_m, m); - if (bn_cmp_abs(_m, n) == RLC_GT) { - bn_mod(_m, _m, n); - } + bn_mod(_k, k, n); + bn_mod(_m, m, n); #if defined(EP_ENDOM) #if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO) @@ -751,14 +994,14 @@ void ep_mul_sim_gen(ep_t r, const bn_t k, const ep_t q, const bn_t m) { } } -void ep_mul_sim_dig(ep_t r, const ep_t p[], const dig_t k[], int len) { +void ep_mul_sim_dig(ep_t r, const ep_t p[], const dig_t k[], int n) { ep_t t; int max; ep_null(t); max = util_bits_dig(k[0]); - for (int i = 1; i < len; i++) { + for (int i = 1; i < n; i++) { max = RLC_MAX(max, util_bits_dig(k[i])); } @@ -768,7 +1011,7 @@ void ep_mul_sim_dig(ep_t r, const ep_t p[], const dig_t k[], int len) { ep_set_infty(t); for (int i = max - 1; i >= 0; i--) { ep_dbl(t, t); - for (int j = 0; j < len; j++) { + for (int j = 0; j < n; j++) { if (k[j] & ((dig_t)1 << i)) { ep_add(t, t, p[j]); } @@ -785,65 +1028,25 @@ void ep_mul_sim_dig(ep_t r, const ep_t p[], const dig_t k[], int len) { } } -void ep_mul_sim_lot(ep_t r, ep_t p[], const bn_t k[], int n) { - int i, j, l, *_l = RLC_ALLOCA(int, n); - ep_t *_p = RLC_ALLOCA(ep_t, n); - int8_t *naf = NULL; - - RLC_TRY { - l = 0; - for (i = 0; i < n; i++) { - l = RLC_MAX(l, bn_bits(k[i]) + 1); - } - naf = RLC_ALLOCA(int8_t, n * l); - if (naf == NULL || _p == NULL || _l == NULL) { - RLC_THROW(ERR_NO_MEMORY); - } - - for (i = 0; i < n; i++) { - ep_null(_p[i]); - ep_new(_p[i]); - } - - - for (i = 0; i < n; i++) { - _l[i] = l; - ep_norm(_p[i], p[i]); - bn_rec_naf(&naf[i*l], &_l[i], k[i], 2); - if (bn_sign(k[i]) == RLC_NEG) { - ep_neg(_p[i], _p[i]); - } - } - - for (i = 0; i < n; i++) { - for (j = _l[i]; j < l; j++) { - naf[i*l + j] = 0; - } - } +void ep_mul_sim_lot(ep_t r, const ep_t p[], const bn_t k[], int n) { + int flag = 0; + if (n == 0) { ep_set_infty(r); - for (i = l - 1; i >= 0; i--) { - ep_dbl(r, r); - for (j = 0; j < n; j++) { - if (naf[j*l + i] > 0) { - ep_add(r, r, _p[j]); - } - if (naf[j*l + i] < 0) { - ep_sub(r, r, _p[j]); - } - } - } + return; + } - /* Convert r to affine coordinates. */ - ep_norm(r, r); - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - for (i = 0; i < n; i++) { - ep_free(_p[i]); - } - RLC_FREE(_l); - RLC_FREE(_p); - RLC_FREE(naf); +#if defined(EP_ENDOM) + if (ep_curve_is_endom()) { + ep_mul_sim_lot_endom(r, p, k, n); + flag = 1; } +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) + if (!flag) { + ep_mul_sim_lot_plain(r, p, k, n); + } +#endif + (void)flag; } diff --git a/contrib/relic/src/ep/relic_ep_norm.c b/contrib/relic/src/ep/relic_ep_norm.c index 4499a3d02..f5c924529 100644 --- a/contrib/relic/src/ep/relic_ep_norm.c +++ b/contrib/relic/src/ep/relic_ep_norm.c @@ -132,10 +132,11 @@ void ep_norm_sim(ep_t *r, const ep_t *t, int n) { fp_copy(r[i]->z, a[i]); } } - +#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) for (i = 0; i < n; i++) { ep_norm_imp(r[i], r[i], 1); } +#endif /* EP_ADD == PROJC */ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/ep/relic_ep_param.c b/contrib/relic/src/ep/relic_ep_param.c index bc250d6ec..cfc50f881 100644 --- a/contrib/relic/src/ep/relic_ep_param.c +++ b/contrib/relic/src/ep/relic_ep_param.c @@ -355,8 +355,6 @@ #define BN_P254_Y "1" #define BN_P254_R "2523648240000001BA344D8000000007FF9F800000000010A10000000000000D" #define BN_P254_H "1" -#define BN_P254_BETA "25236482400000017080EB4000000006181800000000000CD98000000000000B" -#define BN_P254_LAMB "252364824000000126CD8900000000024908FFFFFFFFFFFCF9FFFFFFFFFFFFF6" #define BN_P254_MAPU "-1" /** @} */ #endif @@ -389,12 +387,25 @@ #define BN_P256_Y "4" #define BN_P256_R "B64000000000FF2F2200000085FD547FD8001F44B6B7F4B7C2BC818F7B6BEF99" #define BN_P256_H "1" -#define BN_P256_BETA "B64000000000FF2E2F00000085FC555230001F445D656FB022BC77236CD54C89" -#define BN_P256_LAMB "B64000000000FF2D3C00000085FB562050001F44040FF68D82BC6CB6D9E8694E" #define BN_P256_MAPU "1" /** @} */ #endif +#if defined(EP_ENDOM) && FP_PRIME == 256 +/** + * Parameters for a 256-bit pairing-friendly prime curve standardized in China. + */ +/** @{ */ +#define SM9_P256_A "0" +#define SM9_P256_B "5" +#define SM9_P256_X "93DE051D62BF718FF5ED0704487D01D6E1E4086909DC3280E8C4E4817C66DDDD" +#define SM9_P256_Y "21FE8DDA4F21E607631065125C395BBC1C1C00CBFA6024350C464CD70A3EA616" +#define SM9_P256_R "B640000002A3A6F1D603AB4FF58EC74449F2934B18EA8BEEE56EE19CD69ECF25" +#define SM9_P256_H "1" +#define SM9_P256_MAPU "-1" +/** @} */ +#endif + #if defined(EP_ENDOM) && FP_PRIME == 381 /** * Parameters for a 381-bit pairing-friendly prime curve. @@ -431,9 +442,22 @@ #define BN_P382_Y "1" #define BN_P382_R "24009015183F94892D996CC179C6D1666F82CEFBE47879BB46E4CDA2E2E2281D08DC008E80108252004200000000000D" #define BN_P382_H "1" -#define BN_P382_BETA "4800D81F38406C6AA53C1444D128028A40C60B760288002AC006C0F3001B000000000007" -#define BN_P382_LAMB "9001B03E7080D8D54A78288AC2524566A1E61CA70654006D801382BE004E000000000016" -#define BN_P382_MAPU "-1" +#define BN_P382_MAPU "2" +/** @} */ +#endif + +#if defined(EP_ENDOM) && FP_PRIME == 383 +/** + * Parameters for a 383-bit pairing-friendly prime curve. + */ +/** @{ */ +#define B12_P383_A "0" +#define B12_P383_B "4" +#define B12_P383_X "4ECB5D037AAE9F176171C5D83FC0D6C7AB9195D3D1442B4809F4A6F577722D5DADC9737D5D368545441992AB647A89BE" +#define B12_P383_Y "DD3BFDE4A26B777CEDA2A8F1C4C4E6192C586D8227CC05A34705CCC5A32288C0944408D54909F31BF5C664E81778B03" +#define B12_P383_R "1002001800C00B809C04401C81698B381DE05F095A120D3973B2099EBFEBC0001" +#define B12_P383_H "555AAAC000AABBFFB550556155169EAB" +#define B12_P383_MAPU "5" /** @} */ #endif @@ -448,8 +472,6 @@ #define BN_P446_Y "10" #define BN_P446_R "2400000000000000002400000002D00000000D800000021C00000017A0000000870000000AD400000054C000000156000000126000000061" #define BN_P446_H "1" -#define BN_P446_BETA "4800000000000000003600000004800000000D800000024000000019E00000004800000006300000002E" -#define BN_P446_LAMB "9000000000000000006C00000007E00000001B00000003F000000027C00000007E00000009600000003D" #define BN_P446_MAPU "1" #endif @@ -481,23 +503,6 @@ #define B12_P455_MAPU "-1" #endif -#if defined(EP_ENDOM) && FP_PRIME == 477 -/** - * Parameters for a 477-bit pairing-friendly prime curve at the 192-bit security level. - */ -/** @{ */ -#define B24_P477_A "0" -#define B24_P477_B "4" -#define B24_P477_X "15DFD8E4893A408A34B600532B51CC86CAB3AF07103CFCF3EC7B9AF836904CFB60AB0FA8AC91EE6255E5EF6286FA0C24DF9D76EA50599C2E103E40AD" -#define B24_P477_Y "0A683957A59B1B488FA657E11B44815056BDE33C09D6AAD392D299F89C7841B91A683BF01B7E70547E48E0FBE1CA9E991983131470F886BA9B6FCE2E" -#define B24_P477_R "57F52EE445CC41781FCD53D13E45F6ACDFE4F9F2A3CD414E71238AFC9FCFC7D38CAEF64F4FF79F90013FFFFFF0000001" -#define B24_P477_H "41550AAAC04B3FD5000015AB" -#define B24_P477_BETA "13D9011CCEAD3E74042D5F515F5F04BD3F8EDD703A4BC74ADDB36A479C0D9AD61475466C5CC1F64BC109A18B162560A1743C98DEF233CCCB5F717BEC" -#define B24_P477_LAMB "1001740B431D14BFD17F4BD000300173FFFFFFFEFFFFFFFED" -#define B24_P477_MAPU "1" -/** @} */ -#endif - #if defined(EP_ENDOM) && FP_PRIME == 508 /** * Parameters for a 508-bit pairing-friendly prime curve at the 192-bit security level. @@ -515,6 +520,21 @@ /** @} */ #endif +#if defined(EP_ENDOM) && FP_PRIME == 509 +/** + * Parameters for a 477-bit pairing-friendly prime curve at the 192-bit security level. + */ +/** @{ */ +#define B24_P509_A "0" +#define B24_P509_B "1" +#define B24_P509_X "3A1ADC72F714991991F491FA07B2429302EE6CB4FD3A8663BA38F36F81984232A749B91C286A4579F7736D120DC572C42719E75C7F58AC1426DB4827CF4A46A" +#define B24_P509_Y "101264A0ACB6129DE3CEB5FF829968E5030855FAD666E88506531D46050023ACB15843C4EA8F8AB478F618D263D4B6271D5972803F2046DDD7C7DBC2F6232FFD" +#define B24_P509_R "100000FFFF870FF91CE195DB5B6F3EBD1E08C94C9E193B724ED58B907FF7C311A80D7CABC647746AE3ECB627C943998457FE001" +#define B24_P509_H "155555AAAA805FFFAAC0154AAC" +#define B24_P509_MAPU "2" +/** @} */ +#endif + #if defined(EP_ENDOM) && FP_PRIME == 511 /** * Parameters for the 511-bit jacobi quartic curve. @@ -537,15 +557,15 @@ * Parameters for the 544-bit Cocks-Pinch curve. */ /** @{ */ -#define CP8_P544_A "2" -#define CP8_P544_B "0" -#define CP8_P544_X "251670DB162D336F28505AE026E94316A074EFF8A26AD412D22C58A9CD154E4643CFC40DE884D3D54B95455267566445CB284DF1E413E11CB190BB760CD5665B12456771" -#define CP8_P544_Y "A18EC01733AE4D3AA2B087933D739A4987D839A136695CEE9D7C5B0E24EC62754B70DCD5EFE918C626728C2C31BD9616BC2F724015BCC2CF4DD139897799DA9D198B26CF" -#define CP8_P544_R "FF0060739E18D7594A978B0AB6AE4CE3DBFD52A9D00197603FFFDF0000000101" -#define CP8_P544_H "BC5A106E29D336CBF340F2BB98248FFC0719523D3233C6B3909C882E2BD2251BD3B22F14" -#define CP8_P544_BETA "AEB8BAFC09BEB98DE5FB37D9FC56F9EAC4F908F09D88B1CD8622513C94499803C18F54E6B4FB9180292A2FD4C8AFD2AF43F54BCF308198872F3A6B591394AED0EBF7961A" -#define CP8_P544_LAMB "FF801041EF80043901FFFEF800000010" -#define CP8_P544_MAPU "5" +#define GMT8_P544_A "2" +#define GMT8_P544_B "0" +#define GMT8_P544_X "251670DB162D336F28505AE026E94316A074EFF8A26AD412D22C58A9CD154E4643CFC40DE884D3D54B95455267566445CB284DF1E413E11CB190BB760CD5665B12456771" +#define GMT8_P544_Y "A18EC01733AE4D3AA2B087933D739A4987D839A136695CEE9D7C5B0E24EC62754B70DCD5EFE918C626728C2C31BD9616BC2F724015BCC2CF4DD139897799DA9D198B26CF" +#define GMT8_P544_R "FF0060739E18D7594A978B0AB6AE4CE3DBFD52A9D00197603FFFDF0000000101" +#define GMT8_P544_H "BC5A106E29D336CBF340F2BB98248FFC0719523D3233C6B3909C882E2BD2251BD3B22F14" +#define GMT8_P544_BETA "AEB8BAFC09BEB98DE5FB37D9FC56F9EAC4F908F09D88B1CD8622513C94499803C18F54E6B4FB9180292A2FD4C8AFD2AF43F54BCF308198872F3A6B591394AED0EBF7961A" +#define GMT8_P544_LAMB "FF801041EF80043901FFFEF800000010" +#define GMT8_P544_MAPU "5" #endif /** @} */ @@ -743,6 +763,7 @@ static inline void ep_param_set_ctmap(const char *a_str, const char *b_str, coeffs->deg_yn = ep_param_get_coeffs(coeffs->yn, yn_str); coeffs->deg_yd = ep_param_get_coeffs(coeffs->yd, yd_str); } + #endif /* EP_CTMAP */ /*============================================================================*/ @@ -877,6 +898,11 @@ void ep_param_set(int param) { ASSIGN(SECG_K256, SECG_256); endom = 1; break; + case SM9_P256: + ASSIGN(SM9_P256, SM9_256); + endom = 1; + pairf = EP_BN; + break; case BN_P256: ASSIGN(BN_P256, BN_256); endom = 1; @@ -913,6 +939,13 @@ void ep_param_set(int param) { plain = 1; break; #endif +#if defined(EP_ENDOM) && FP_PRIME == 383 + case B12_P383: + ASSIGN(B12_P383, B12_383); + endom = 1; + pairf = EP_B12; + break; +#endif #if defined(EP_PLAIN) && FP_PRIME == 384 case NIST_P384: ASSIGN(NIST_P384, NIST_384); @@ -938,18 +971,19 @@ void ep_param_set(int param) { pairf = EP_B12; break; #endif -#if defined(EP_ENDOM) && FP_PRIME == 477 - case B24_P477: - ASSIGNK(B24_P477, B24_477); - plain = 1; - break; -#endif #if defined(EP_ENDOM) && FP_PRIME == 508 case KSS_P508: ASSIGNK(KSS_P508, KSS_508); endom = 1; break; #endif +#if defined(EP_ENDOM) && FP_PRIME == 509 + case B24_P509: + ASSIGN(B24_P509, B24_509); + endom = 1; + pairf = EP_B24; + break; +#endif #if defined(EP_ENDOM) && FP_PRIME == 511 case OT8_P511: ASSIGNK(OT8_P511, OT_511); @@ -969,8 +1003,8 @@ void ep_param_set(int param) { break; #endif #if defined(EP_ENDOM) && FP_PRIME == 544 - case CP8_P544: - ASSIGN(CP8_P544, CP8_544); + case GMT8_P544: + ASSIGN(GMT8_P544, GMT8_544); endom = 1; break; #endif @@ -1043,6 +1077,18 @@ void ep_param_set(int param) { bn_sqr(lamb, lamb); bn_sub_dig(lamb, lamb, 1); break; + case EP_B24: + /* beta = (-1 + sqrt(-3))/2, lambda = z^4 - 1. */ + fp_set_dig(beta, 3); + fp_neg(beta, beta); + fp_srt(beta, beta); + fp_sub_dig(beta, beta, 1); + fp_hlv(beta, beta); + fp_prime_get_par(lamb); + bn_sqr(lamb, lamb); + bn_sqr(lamb, lamb); + bn_sub_dig(lamb, lamb, 1); + break; default: if (bn_cmp_dig(h, 1) == RLC_EQ) { /* SECG curves with endomorphisms. */ @@ -1188,6 +1234,8 @@ int ep_param_set_any_endom(void) { ep_param_set(B12_P381); #elif FP_PRIME == 382 ep_param_set(BN_P382); +#elif FP_PRIME == 383 + ep_param_set(B12_P383); #elif FP_PRIME == 446 #ifdef FP_QNRES ep_param_set(B12_P446); @@ -1196,14 +1244,14 @@ int ep_param_set_any_endom(void) { #endif #elif FP_PRIME == 455 ep_param_set(B12_P455); -#elif FP_PRIME == 477 - ep_param_set(B24_P477); #elif FP_PRIME == 508 ep_param_set(KSS_P508); +#elif FP_PRIME == 509 + ep_param_set(B24_P509); #elif FP_PRIME == 511 ep_param_set(OT8_P511); #elif FP_PRIME == 544 - ep_param_set(CP8_P544); + ep_param_set(GMT8_P544); #elif FP_PRIME == 638 #ifdef FP_QNRES ep_param_set(B12_P638); @@ -1258,6 +1306,10 @@ int ep_param_set_any_pairf(void) { ep_param_set(BN_P382); type = RLC_EP_DTYPE; degree = 2; +#elif FP_PRIME == 383 + ep_param_set(B12_P383); + type = RLC_EP_MTYPE; + degree = 2; #elif FP_PRIME == 446 #ifdef FP_QNRES ep_param_set(B12_P446); @@ -1272,20 +1324,20 @@ int ep_param_set_any_pairf(void) { ep_param_set(B12_P455); type = RLC_EP_DTYPE; degree = 2; -#elif FP_PRIME == 477 - ep_param_set(B24_P477); - type = RLC_EP_MTYPE; - degree = 4; #elif FP_PRIME == 508 ep_param_set(KSS_P508); type = RLC_EP_DTYPE; degree = 3; +#elif FP_PRIME == 509 + ep_param_set(B24_P509); + type = RLC_EP_DTYPE; + degree = 4; #elif FP_PRIME == 511 ep_param_set(OT8_P511); type = RLC_EP_DTYPE; degree = 2; #elif FP_PRIME == 544 - ep_param_set(CP8_P544); + ep_param_set(GMT8_P544); type = RLC_EP_MTYPE; degree = 2; #elif FP_PRIME == 569 @@ -1323,10 +1375,15 @@ int ep_param_set_any_pairf(void) { switch (degree) { case 0: ep2_curve_set_twist(0); + /* Compute pairing generator. */ + pc_core_calc(); break; case 2: ep2_curve_set_twist(type); break; + case 4: + ep4_curve_set_twist(type); + break; } } #else @@ -1383,14 +1440,20 @@ void ep_param_print(void) { case BN_P256: util_banner("Curve BN-P256:", 0); break; - case BN_P382: - util_banner("Curve BN-P382:", 0); + case SM9_P256: + util_banner("Curve SM9-P256:", 0); break; case B12_P381: util_banner("Curve B12-P381:", 0); break; - case CP8_P544: - util_banner("Curve CP8-P544:", 0); + case BN_P382: + util_banner("Curve BN-P382:", 0); + break; + case B12_P383: + util_banner("Curve B12-P383:", 0); + break; + case GMT8_P544: + util_banner("Curve GMT8-P544:", 0); break; case BN_P446: util_banner("Curve BN-P446:", 0); @@ -1401,12 +1464,12 @@ void ep_param_print(void) { case B12_P455: util_banner("Curve B12-P455:", 0); break; - case B24_P477: - util_banner("Curve B24-P477:", 0); - break; case KSS_P508: util_banner("Curve KSS-P508:", 0); break; + case B24_P509: + util_banner("Curve B24-P509:", 0); + break; case OT8_P511: util_banner("Curve OT8-P511:", 0); break; @@ -1458,6 +1521,7 @@ int ep_param_level(void) { return 112; case BN_P254: case BN_P256: + case SM9_P256: return 112; case NIST_P256: case SECG_K256: @@ -1466,14 +1530,16 @@ int ep_param_level(void) { return 128; case B12_P381: case BN_P382: + case B12_P383: case BN_P446: case B12_P446: - case CP8_544: + case GMT8_544: case SS_P1536: return 128; case B12_P455: return 140; case NIST_P384: + case B24_P509: return 192; case NIST_P521: return 256; @@ -1486,22 +1552,26 @@ int ep_param_level(void) { int ep_param_embed(void) { switch (ep_param_get()) { + case SS_P1536: + return 2; + case OT8_P511: + case GMT8_P544: + return 8; case BN_P158: case BN_P254: case BN_P256: + case SM9_P256: case BN_P382: case BN_P446: case B12_P446: case BN_P638: case B12_P381: + case B12_P383: case B12_P455: case B12_P638: return 12; - case SS_P1536: - return 2; - case OT8_P511: - case CP8_P544: - return 8; + case B24_P509: + return 24; case B48_P575: return 48; case K54_P569: diff --git a/contrib/relic/src/ep/relic_ep_psi.c b/contrib/relic/src/ep/relic_ep_psi.c index b353f459f..c700be38c 100644 --- a/contrib/relic/src/ep/relic_ep_psi.c +++ b/contrib/relic/src/ep/relic_ep_psi.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2009 RELIC Authors + * Copyright (c) 2021 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/ep/relic_ep_util.c b/contrib/relic/src/ep/relic_ep_util.c index 8b97aca51..54b13eab9 100644 --- a/contrib/relic/src/ep/relic_ep_util.c +++ b/contrib/relic/src/ep/relic_ep_util.c @@ -83,7 +83,6 @@ void ep_blind(ep_t r, const ep_t p) { RLC_TRY { fp_new(rand); - fp_rand(rand); #if EP_ADD == BASIC (void)rand; @@ -278,6 +277,11 @@ void ep_read_bin(ep_t a, const uint8_t *bin, int len) { return; } } + + if (!ep_on_curve(a)) { + RLC_THROW(ERR_NO_VALID); + return; + } } void ep_write_bin(uint8_t *bin, int len, const ep_t a, int pack) { @@ -285,12 +289,13 @@ void ep_write_bin(uint8_t *bin, int len, const ep_t a, int pack) { ep_null(t); + memset(bin, 0, len); + if (ep_is_infty(a)) { if (len < 1) { RLC_THROW(ERR_NO_BUFFER); return; } else { - bin[0] = 0; return; } } diff --git a/contrib/relic/src/epx/relic_ep2_curve.c b/contrib/relic/src/epx/relic_ep2_curve.c index dfc60515f..cdf301946 100644 --- a/contrib/relic/src/epx/relic_ep2_curve.c +++ b/contrib/relic/src/epx/relic_ep2_curve.c @@ -92,6 +92,23 @@ /** @} */ #endif +#if defined(EP_ENDOM) && FP_PRIME == 256 +/** @{ */ +#define SM9_P256_A0 "0" +#define SM9_P256_A1 "0" +#define SM9_P256_B0 "0" +#define SM9_P256_B1 "5" +#define SM9_P256_X0 "3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B" +#define SM9_P256_X1 "85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141" +#define SM9_P256_Y0 "A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7" +#define SM9_P256_Y1 "17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96" +#define SM9_P256_R "B640000002A3A6F1D603AB4FF58EC74449F2934B18EA8BEEE56EE19CD69ECF25" +#define SM9_P256_H "B640000002A3A6F1D603AB4FF58EC745F9F2934B1C0B51C8E57054B2F003BBD5" +#define SM9_P256_MAPU0 "-1" +#define SM9_P256_MAPU1 "0" +/** @} */ +#endif + #if defined(EP_ENDOM) && FP_PRIME == 381 /** @{ */ #define B12_P381_A0 "0" @@ -139,6 +156,23 @@ /** @} */ #endif +#if defined(EP_ENDOM) && FP_PRIME == 383 +/** @{ */ +#define B12_P383_A0 "0" +#define B12_P383_A1 "0" +#define B12_P383_B0 "4" +#define B12_P383_B1 "4" +#define B12_P383_X0 "2E4DCF4E55CBA1075B3325DD25C2B80BD907686E55E175F0B5D097E46E78B6B5F8E600B80D2EBD4E410BCCCBAE018976" +#define B12_P383_X1 "0BE0128C473D6A90202AC72A60E988CF7901242A2A4623A89253256CC11C1519D3C633897E071D8F466EA0BFFA5F9313" +#define B12_P383_Y0 "44900D049962DF1BBCB29872FDA90D0DFC2253033569F7D684080F6A5B4F669120A29F908FED5B64AAA9A56502405B39" +#define B12_P383_Y1 "1459B073246773B35CBCBFC9318AC47DDC1C284887D1DA4BE13593ACC0E45B748AF4115011A3EA730A7DB21A83562411" +#define B12_P383_R "1002001800C00B809C04401C81698B381DE05F095A120D3973B2099EBFEBC0001" +#define B12_P383_H "1C78E45562AB68EE641721902ED56C9B45EB1276A5C15CB19C7BF81F7A7B6F22053BAC3422240A3F4A7E3C25D470E7BABDB8A2E1E1793BF9CEBDD1BF2EFE30E5" +#define B12_P383_MAPU0 "0" +#define B12_P383_MAPU1 "1" +/** @} */ +#endif + #if defined(EP_ENDOM) && FP_PRIME == 446 /** @{ */ #define BN_P446_A0 "0" @@ -209,18 +243,18 @@ #if defined(EP_ENDOM) && FP_PRIME == 544 /** @{ */ -#define CP8_P544_A0 "0" -#define CP8_P544_A1 "2" -#define CP8_P544_B0 "0" -#define CP8_P544_B1 "0" -#define CP8_P544_X0 "1EE84A939A46EAE4287805E2FFABBCED3605B74F5FD7E545F390D2E3D34AD0C60851EA65A18CF92396B9318FCAB3205D79C8D03E928590F719E4086A1C42AF2D40EB6C3A" -#define CP8_P544_X1 "065F721D63381C07D1BF556D65A3A82B0E969BA031FB3812F49709926D5159324DFB685048D4EAFC914F893A0D5382868D1D252619AA964149258DCC1A86B68775F36A82" -#define CP8_P544_Y0 "9B80046683050F459F48D7CE4C83992D5B044718326AEE2DD86F3E5557BD240441A763BC40030F21FC3A64483B450330930BAFA62E7B573B565404A9DB2A5BFF7D6994D4" -#define CP8_P544_Y1 "AB457A64E140799D3D9B77ECEA828957F3AEADB3278FEE32E9AD77F068DD2F95B469607E8CE3CE5705276F869CFB18270C0A8FC8D8AD0D17545F4DCCC9E599853A7BAB76" -#define CP8_P544_R "FF0060739E18D7594A978B0AB6AE4CE3DBFD52A9D00197603FFFDF0000000101" -#define CP8_P544_H "8A0A079FC7C3D421A4986FAAA10A6593F60BC94E32AEE8067E35551B86D59F0F61BD6A750917746236DD39CB4710BD44B7BE86F0A8E5324DFE802973060F04BF37C018705B78072182D139A8D2BD338A630511676FDAFD47C60DB5393F9DFC96089B1FFB60B78FB2" -#define CP8_P544_MAPU0 "0" -#define CP8_P544_MAPU1 "1" +#define GMT8_P544_A0 "0" +#define GMT8_P544_A1 "2" +#define GMT8_P544_B0 "0" +#define GMT8_P544_B1 "0" +#define GMT8_P544_X0 "1EE84A939A46EAE4287805E2FFABBCED3605B74F5FD7E545F390D2E3D34AD0C60851EA65A18CF92396B9318FCAB3205D79C8D03E928590F719E4086A1C42AF2D40EB6C3A" +#define GMT8_P544_X1 "065F721D63381C07D1BF556D65A3A82B0E969BA031FB3812F49709926D5159324DFB685048D4EAFC914F893A0D5382868D1D252619AA964149258DCC1A86B68775F36A82" +#define GMT8_P544_Y0 "9B80046683050F459F48D7CE4C83992D5B044718326AEE2DD86F3E5557BD240441A763BC40030F21FC3A64483B450330930BAFA62E7B573B565404A9DB2A5BFF7D6994D4" +#define GMT8_P544_Y1 "AB457A64E140799D3D9B77ECEA828957F3AEADB3278FEE32E9AD77F068DD2F95B469607E8CE3CE5705276F869CFB18270C0A8FC8D8AD0D17545F4DCCC9E599853A7BAB76" +#define GMT8_P544_R "FF0060739E18D7594A978B0AB6AE4CE3DBFD52A9D00197603FFFDF0000000101" +#define GMT8_P544_H "8A0A079FC7C3D421A4986FAAA10A6593F60BC94E32AEE8067E35551B86D59F0F61BD6A750917746236DD39CB4710BD44B7BE86F0A8E5324DFE802973060F04BF37C018705B78072182D139A8D2BD338A630511676FDAFD47C60DB5393F9DFC96089B1FFB60B78FB2" +#define GMT8_P544_MAPU0 "0" +#define GMT8_P544_MAPU1 "1" /** @} */ #endif @@ -478,7 +512,7 @@ static void detect_opt(int *opt, fp2_t a) { RLC_TRY { fp2_new(t); fp2_set_dig(t, 3); - fp_neg(t[0], t[0]); + fp2_neg(t, t); if (fp2_cmp(a, t) == RLC_EQ) { *opt = RLC_MIN3; @@ -523,6 +557,8 @@ void ep2_curve_init(void) { for (unsigned i = 0; i < 4; ++i) { fp2_new(ctx->ep2_map_c[i]); } + fp2_new(ctx->ep2_frb[0]); + fp2_new(ctx->ep2_frb[1]); #endif #ifdef EP_PRECO @@ -535,8 +571,8 @@ void ep2_curve_init(void) { #endif #endif ep2_set_infty(ctx->ep2_g); - bn_init(&(ctx->ep2_r), RLC_FP_DIGS); - bn_init(&(ctx->ep2_h), RLC_FP_DIGS); + bn_make(&(ctx->ep2_r), RLC_FP_DIGS); + bn_make(&(ctx->ep2_h), RLC_FP_DIGS); #ifdef EP_CTMAP iso2_t iso = ep2_curve_get_iso(); @@ -590,6 +626,8 @@ void ep2_curve_clean(void) { for (unsigned i = 0; i < 4; ++i) { fp2_free(ctx->ep2_map_c[i]); } + fp2_free(ctx->ep2_frb[0]); + fp2_free(ctx->ep2_frb[1]); } } @@ -706,8 +744,7 @@ void ep2_curve_set_twist(int type) { char str[4 * RLC_FP_BYTES + 1]; ctx_t *ctx = core_get(); ep2_t g; - fp2_t a; - fp2_t b, u; + fp2_t a, b, u; bn_t r, h; ep2_null(g); @@ -745,6 +782,9 @@ void ep2_curve_set_twist(int type) { case BN_P256: ASSIGN(BN_P256); break; + case SM9_P256: + ASSIGN(SM9_P256); + break; #elif FP_PRIME == 381 case B12_P381: ASSIGN(B12_P381); @@ -757,6 +797,10 @@ void ep2_curve_set_twist(int type) { case BN_P382: ASSIGN(BN_P382); break; +#elif FP_PRIME == 383 + case B12_P383: + ASSIGN(B12_P383); + break; #elif FP_PRIME == 446 case BN_P446: ASSIGN(BN_P446); @@ -773,8 +817,8 @@ void ep2_curve_set_twist(int type) { ASSIGN(OT8_P511); break; #elif FP_PRIME == 544 - case CP8_P544: - ASSIGN(CP8_P544); + case GMT8_P544: + ASSIGN(GMT8_P544); break; #elif FP_PRIME == 638 case BN_P638: @@ -791,7 +835,7 @@ void ep2_curve_set_twist(int type) { } fp2_zero(g->z); - fp_set_dig(g->z[0], 1); + fp2_set_dig(g->z, 1); g->coord = BASIC; ep2_copy(ctx->ep2_g, g); @@ -808,6 +852,15 @@ void ep2_curve_set_twist(int type) { /* I don't have a better place for this. */ fp_prime_calc(); + fp_copy(ctx->ep2_frb[0][0], ctx->fp2_p1[1][0]); + fp_copy(ctx->ep2_frb[0][1], ctx->fp2_p1[1][1]); + fp_copy(ctx->ep2_frb[1][0], ctx->fp2_p1[2][0]); + fp_copy(ctx->ep2_frb[1][1], ctx->fp2_p1[2][1]); + if (type == RLC_EP_MTYPE) { + fp2_inv(ctx->ep2_frb[0], ctx->ep2_frb[0]); + fp2_inv(ctx->ep2_frb[1], ctx->ep2_frb[1]); + } + /* compute constants for hash-to-curve */ ep2_curve_set_map(); @@ -837,10 +890,8 @@ void ep2_curve_set(fp2_t a, fp2_t b, ep2_t g, bn_t r, bn_t h) { ctx_t *ctx = core_get(); ctx->ep2_is_twist = 0; - fp_copy(ctx->ep2_a[0], a[0]); - fp_copy(ctx->ep2_a[1], a[1]); - fp_copy(ctx->ep2_b[0], b[0]); - fp_copy(ctx->ep2_b[1], b[1]); + fp2_copy(ctx->ep2_a, a); + fp2_copy(ctx->ep2_b, b); ep2_norm(ctx->ep2_g, g); bn_copy(&(ctx->ep2_r), r); diff --git a/contrib/relic/src/epx/relic_ep2_frb.c b/contrib/relic/src/epx/relic_ep2_frb.c index c2d7e0143..e16be1702 100644 --- a/contrib/relic/src/epx/relic_ep2_frb.c +++ b/contrib/relic/src/epx/relic_ep2_frb.c @@ -37,18 +37,14 @@ /*============================================================================*/ void ep2_frb(ep2_t r, ep2_t p, int i) { + ctx_t *ctx = core_get(); + ep2_copy(r, p); for (; i > 0; i--) { fp2_frb(r->x, r->x, 1); fp2_frb(r->y, r->y, 1); fp2_frb(r->z, r->z, 1); - if (ep2_curve_is_twist() == RLC_EP_MTYPE) { - fp2_mul_frb(r->x, r->x, 1, 4); - fp2_mul_art(r->x, r->x); - fp2_mul_art(r->y, r->y); - } else { - fp2_mul_frb(r->x, r->x, 1, 2); - } - fp2_mul_frb(r->y, r->y, 1, 3); + fp2_mul(r->x, r->x, ctx->ep2_frb[0]); + fp2_mul(r->y, r->y, ctx->ep2_frb[1]); } } diff --git a/contrib/relic/src/epx/relic_ep2_map.c b/contrib/relic/src/epx/relic_ep2_map.c index bf45f373f..7764679ab 100644 --- a/contrib/relic/src/epx/relic_ep2_map.c +++ b/contrib/relic/src/epx/relic_ep2_map.c @@ -89,83 +89,103 @@ static inline int fp2_sgn0(const fp2_t t, bn_t k) { /* Public definitions */ /*============================================================================*/ -void ep2_map_dst(ep2_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst_len) { - bn_t k; - fp2_t t; - ep2_t q; - int neg; - /* enough space for two extension field elements plus extra bytes for uniformity */ - const int len_per_elm = (FP_PRIME + ep_param_level() + 7) / 8; - uint8_t *pseudo_random_bytes = RLC_ALLOCA(uint8_t, 4 * len_per_elm); - - bn_null(k); - fp2_null(t); - ep2_null(q); - - RLC_TRY { - bn_new(k); - fp2_new(t); - ep2_new(q); - - /* which hash function should we use? */ - const int abNeq0 = (ep2_curve_opt_a() != RLC_ZERO) && (ep2_curve_opt_b() != RLC_ZERO); - void (*const map_fn)(ep2_t, fp2_t) = (ep2_curve_is_ctmap() || abNeq0) ? ep2_map_sswu : ep2_map_svdw; - - /* XXX(rsw) See note in ep/relic_ep_map.c about using MD_MAP. */ - /* hash to a pseudorandom string using md_xmd */ - md_xmd(pseudo_random_bytes, 4 * len_per_elm, msg, len, dst, dst_len); +void ep2_map_from_field(ep2_t p, const uint8_t *uniform_bytes, int len) { + bn_t k; + fp2_t t; + ep2_t q; + int neg; + /* enough space for two extension field elements plus extra bytes for uniformity */ + const int len_per_elm = (FP_PRIME + ep_param_level() + 7) / 8; + + bn_null(k); + fp2_null(t); + ep2_null(q); + + RLC_TRY { + if (len != 2* len_per_elm) { + RLC_THROW(ERR_NO_VALID); + } + + bn_new(k); + fp2_new(t); + ep2_new(q); + + /* which hash function should we use? */ + const int abNeq0 = (ep2_curve_opt_a() != RLC_ZERO) && (ep2_curve_opt_b() != RLC_ZERO); + void (*const map_fn)(ep2_t, fp2_t) = (ep2_curve_is_ctmap() || abNeq0) ? ep2_map_sswu : ep2_map_svdw; #define EP2_MAP_CONVERT_BYTES(IDX) \ - do { \ - bn_read_bin(k, pseudo_random_bytes + 2 * IDX * len_per_elm, len_per_elm); \ - fp_prime_conv(t[0], k); \ - bn_read_bin(k, pseudo_random_bytes + (2 * IDX + 1) * len_per_elm, len_per_elm); \ - fp_prime_conv(t[1], k); \ - } while (0) + do { \ + bn_read_bin(k, uniform_bytes + 2 * IDX * len_per_elm, len_per_elm); \ + fp_prime_conv(t[0], k); \ + bn_read_bin(k, uniform_bytes + (2 * IDX + 1) * len_per_elm, len_per_elm); \ + fp_prime_conv(t[1], k); \ + } while (0) #define EP2_MAP_APPLY_MAP(PT) \ - do { \ - /* sign of t */ \ - neg = fp2_sgn0(t, k); \ - /* convert */ \ - map_fn(PT, t); \ - /* compare sign of y to sign of t; fix if necessary */ \ - neg = neg != fp2_sgn0(PT->y, k); \ - fp2_neg(t, PT->y); \ - dv_copy_cond(PT->y[0], t[0], RLC_FP_DIGS, neg); \ - dv_copy_cond(PT->y[1], t[1], RLC_FP_DIGS, neg); \ - } while (0) + do { \ + /* sign of t */ \ + neg = fp2_sgn0(t, k); \ + /* convert */ \ + map_fn(PT, t); \ + /* compare sign of y to sign of t; fix if necessary */ \ + neg = neg != fp2_sgn0(PT->y, k); \ + fp2_neg(t, PT->y); \ + dv_copy_cond(PT->y[0], t[0], RLC_FP_DIGS, neg); \ + dv_copy_cond(PT->y[1], t[1], RLC_FP_DIGS, neg); \ + } while (0) + + /* first map invocation */ + EP2_MAP_CONVERT_BYTES(0); + EP2_MAP_APPLY_MAP(p); + TMPL_MAP_CALL_ISOMAP(ep2, p); + + /* second map invocation */ + EP2_MAP_CONVERT_BYTES(1); + EP2_MAP_APPLY_MAP(q); + TMPL_MAP_CALL_ISOMAP(ep2, q); + + /* XXX(rsw) could add p and q and then apply isomap, + * but need ep_add to support addition on isogeny curves */ - /* first map invocation */ - EP2_MAP_CONVERT_BYTES(0); - EP2_MAP_APPLY_MAP(p); - TMPL_MAP_CALL_ISOMAP(ep2, p); +#undef EP2_MAP_CONVERT_BYTES +#undef EP2_MAP_APPLY_MAP - /* second map invocation */ - EP2_MAP_CONVERT_BYTES(1); - EP2_MAP_APPLY_MAP(q); - TMPL_MAP_CALL_ISOMAP(ep2, q); + /* sum the result */ + ep2_add(p, p, q); + ep2_norm(p, p); + ep2_mul_cof(p, p); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(k); + fp2_free(t); + ep2_free(q); + } +} - /* XXX(rsw) could add p and q and then apply isomap, - * but need ep_add to support addition on isogeny curves */ -#undef EP2_MAP_CONVERT_BYTES -#undef EP2_MAP_APPLY_MAP +void ep2_map_dst(ep2_t p, const uint8_t *msg, int len, const uint8_t *dst, int dst_len) { - /* sum the result */ - ep2_add(p, p, q); - ep2_norm(p, p); - ep2_mul_cof(p, p); - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - bn_free(k); - fp2_free(t); - ep2_free(q); - RLC_FREE(pseudo_random_bytes); - } + /* enough space for two field elements plus extra bytes for uniformity */ + const int len_per_elm = (FP_PRIME + ep_param_level() + 7) / 8; + uint8_t *pseudo_random_bytes = RLC_ALLOCA(uint8_t, 4 * len_per_elm); + + RLC_TRY { + + /* XXX(rsw) See note in ep/relic_ep_map.c about using MD_MAP. */ + /* hash to a pseudorandom string using md_xmd */ + md_xmd(pseudo_random_bytes, 4 * len_per_elm, msg, len, dst, dst_len); + ep2_map_from_field(p, pseudo_random_bytes, 2 * len_per_elm); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + RLC_FREE(pseudo_random_bytes); + } } void ep2_map(ep2_t p, const uint8_t *msg, int len) { diff --git a/contrib/relic/src/epx/relic_ep2_mul.c b/contrib/relic/src/epx/relic_ep2_mul.c index 7111f130b..beec8ba86 100644 --- a/contrib/relic/src/epx/relic_ep2_mul.c +++ b/contrib/relic/src/epx/relic_ep2_mul.c @@ -41,153 +41,54 @@ #if defined(EP_ENDOM) static void ep2_mul_glv_imp(ep2_t r, ep2_t p, const bn_t k) { - int i, j, l; - bn_t n, _k[4], u[4], v[4]; + int i, j, l, _l[4]; + bn_t n, _k[4], u; + int8_t naf[4][RLC_FP_BITS + 1]; ep2_t q[4]; bn_null(n); + bn_null(u); RLC_TRY { bn_new(n); + bn_new(u); for (i = 0; i < 4; i++) { - bn_null(u[i]); - bn_null(v[i]); bn_null(_k[i]); ep2_null(q[i]); - bn_new(u[i]); - bn_new(v[i]); bn_new(_k[i]); ep2_new(q[i]); } ep2_curve_get_ord(n); - - switch (ep_curve_is_pairf()) { - case EP_BN: - ep2_curve_get_vs(v); - - for (i = 0; i < 4; i++) { - bn_mul(v[i], v[i], k); - bn_div(v[i], v[i], n); - if (bn_sign(v[i]) == RLC_NEG) { - bn_add_dig(v[i], v[i], 1); - } - bn_zero(_k[i]); - } - - /* u0 = x + 1, u1 = 2x + 1, u2 = 2x, u3 = x - 1. */ - fp_prime_get_par(u[0]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[1], u[2], 1); - bn_sub_dig(u[3], u[0], 1); - bn_add_dig(u[0], u[0], 1); - bn_copy(_k[0], k); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[0], _k[0], n); - bn_sub(_k[0], _k[0], u[i]); - bn_mod(_k[0], _k[0], n); - } - - /* u0 = x, u1 = -x, u2 = 2x + 1, u3 = 4x + 2. */ - fp_prime_get_par(u[0]); - bn_neg(u[1], u[0]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[2], u[2], 1); - bn_dbl(u[3], u[2]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[1], _k[1], n); - bn_sub(_k[1], _k[1], u[i]); - bn_mod(_k[1], _k[1], n); - } - - /* u0 = x, u1 = -(x + 1), u2 = 2x + 1, u3 = -(2x - 1). */ - fp_prime_get_par(u[0]); - bn_add_dig(u[1], u[0], 1); - bn_neg(u[1], u[1]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[2], u[2], 1); - bn_sub_dig(u[3], u[2], 2); - bn_neg(u[3], u[3]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[2], _k[2], n); - bn_sub(_k[2], _k[2], u[i]); - bn_mod(_k[2], _k[2], n); - } - - /* u0 = -2x, u1 = -x, u2 = 2x + 1, u3 = x - 1. */ - fp_prime_get_par(u[1]); - bn_dbl(u[0], u[1]); - bn_neg(u[0], u[0]); - bn_dbl(u[2], u[1]); - bn_add_dig(u[2], u[2], 1); - bn_sub_dig(u[3], u[1], 1); - bn_neg(u[1], u[1]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[3], _k[3], n); - bn_sub(_k[3], _k[3], u[i]); - bn_mod(_k[3], _k[3], n); - } - - for (i = 0; i < 4; i++) { - l = bn_bits(_k[i]); - bn_sub(_k[i], n, _k[i]); - if (bn_bits(_k[i]) > l) { - bn_sub(_k[i], _k[i], n); - _k[i]->sign = RLC_POS; - } else { - _k[i]->sign = RLC_NEG; - } - } - break; - default: - bn_abs(v[0], k); - fp_prime_get_par(u[0]); - bn_copy(u[1], u[0]); - if (bn_sign(u[0]) == RLC_NEG) { - bn_neg(u[0], u[0]); - } - - for (i = 0; i < 4; i++) { - bn_mod(_k[i], v[0], u[0]); - bn_div(v[0], v[0], u[0]); - if ((bn_sign(u[1]) == RLC_NEG) && (i % 2 != 0)) { - bn_neg(_k[i], _k[i]); - } - if (bn_sign(k) == RLC_NEG) { - bn_neg(_k[i], _k[i]); - } - } - - break; - } + fp_prime_get_par(u); + bn_mod(_k[0], k, n); + bn_rec_frb(_k, 4, _k[0], u, n, ep_curve_is_pairf() == EP_B12); ep2_norm(q[0], p); ep2_frb(q[1], q[0], 1); ep2_frb(q[2], q[1], 1); ep2_frb(q[3], q[2], 1); + l = 0; for (i = 0; i < 4; i++) { if (bn_sign(_k[i]) == RLC_NEG) { ep2_neg(q[i], q[i]); } + _l[i] = RLC_FP_BITS + 1; + bn_rec_naf(naf[i], &_l[i], _k[i], 2); + l = RLC_MAX(l, _l[i]); } - l = RLC_MAX(bn_bits(_k[0]), bn_bits(_k[1])); - l = RLC_MAX(l, RLC_MAX(bn_bits(_k[2]), bn_bits(_k[3]))); ep2_set_infty(r); - for (i = l - 1; i >= 0; i--) { + for (j = l - 1; j >= 0; j--) { ep2_dbl(r, r); - for (j = 0; j < 4; j++) { - if (bn_get_bit(_k[j], i)) { - ep2_add(r, r, q[j]); + + for (i = 0; i < 4; i++) { + if (naf[i][j] > 0) { + ep2_add(r, r, q[i]); + } + if (naf[i][j] < 0) { + ep2_sub(r, r, q[i]); } } } @@ -200,9 +101,8 @@ static void ep2_mul_glv_imp(ep2_t r, ep2_t p, const bn_t k) { } RLC_FINALLY { bn_free(n); + bn_free(u); for (i = 0; i < 4; i++) { - bn_free(u[i]); - bn_free(v[i]); bn_free(_k[i]); ep2_free(q[i]); } @@ -440,7 +340,7 @@ void ep2_mul_lwnaf(ep2_t r, ep2_t p, const bn_t k) { #if defined(EP_ENDOM) if (ep_curve_is_endom()) { - if (ep_curve_opt_a() == RLC_ZERO) { + if (ep2_curve_opt_a() == RLC_ZERO) { ep2_mul_glv_imp(r, p, k); } else { ep2_mul_naf_imp(r, p, k); @@ -484,10 +384,13 @@ void ep2_mul_gen(ep2_t r, bn_t k) { } void ep2_mul_dig(ep2_t r, ep2_t p, dig_t k) { - int i, l; ep2_t t; + bn_t _k; + int8_t u, naf[RLC_DIG + 1]; + int l; ep2_null(t); + bn_null(_k); if (k == 0 || ep2_is_infty(p)) { ep2_set_infty(r); @@ -496,15 +399,22 @@ void ep2_mul_dig(ep2_t r, ep2_t p, dig_t k) { RLC_TRY { ep2_new(t); + bn_new(_k); - l = util_bits_dig(k); + bn_set_dig(_k, k); - ep2_copy(t, p); + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _k, 2); - for (i = l - 2; i >= 0; i--) { + ep2_set_infty(t); + for (int i = l - 1; i >= 0; i--) { ep2_dbl(t, t); - if (k & ((dig_t)1 << i)) { + + u = naf[i]; + if (u > 0) { ep2_add(t, t, p); + } else if (u < 0) { + ep2_sub(t, t, p); } } @@ -515,5 +425,6 @@ void ep2_mul_dig(ep2_t r, ep2_t p, dig_t k) { } RLC_FINALLY { ep2_free(t); + bn_free(_k); } } diff --git a/contrib/relic/src/epx/relic_ep2_mul_cof.c b/contrib/relic/src/epx/relic_ep2_mul_cof.c index 42a8e3c1c..575c40a17 100644 --- a/contrib/relic/src/epx/relic_ep2_mul_cof.c +++ b/contrib/relic/src/epx/relic_ep2_mul_cof.c @@ -24,7 +24,7 @@ /** * @file * - * Implementation of scalar multiplication of a prime elliptic curve over a + * Implementation of point multiplication of a prime elliptic curve over a * quadratic extension by the curve cofactor. * * @ingroup epx diff --git a/contrib/relic/src/epx/relic_ep2_mul_fix.c b/contrib/relic/src/epx/relic_ep2_mul_fix.c index d16b14dab..fc9e3d9bd 100755 --- a/contrib/relic/src/epx/relic_ep2_mul_fix.c +++ b/contrib/relic/src/epx/relic_ep2_mul_fix.c @@ -38,36 +38,6 @@ #if EP_FIX == LWNAF || !defined(STRIP) -/** - * Precomputes a table for a point multiplication on an ordinary curve. - * - * @param[out] t - the destination table. - * @param[in] p - the point to multiply. - */ -static void ep2_mul_pre_ordin(ep2_t *t, ep2_t p) { - int i; - - ep2_dbl(t[0], p); -#if defined(EP_MIXED) - ep2_norm(t[0], t[0]); -#endif - -#if EP_DEPTH > 2 - ep2_add(t[1], t[0], p); - for (i = 2; i < (1 << (EP_DEPTH - 2)); i++) { - ep2_add(t[i], t[i - 1], t[0]); - } - -#if defined(EP_MIXED) - for (i = 1; i < (1 << (EP_DEPTH - 2)); i++) { - ep2_norm(t[i], t[i]); - } -#endif - -#endif - ep2_copy(t[0], p); -} - /** * Multiplies a binary elliptic curve point by an integer using the w-NAF * method. @@ -76,7 +46,7 @@ static void ep2_mul_pre_ordin(ep2_t *t, ep2_t p) { * @param[in] p - the point to multiply. * @param[in] k - the integer. */ -static void ep2_mul_fix_ordin(ep2_t r, ep2_t *table, bn_t k) { +static void ep2_mul_fix_plain(ep2_t r, ep2_t *table, bn_t k) { int len, i, n; int8_t naf[2 * RLC_FP_BITS + 1], *t; @@ -141,21 +111,38 @@ void ep2_mul_pre_basic(ep2_t *t, ep2_t p) { } void ep2_mul_fix_basic(ep2_t r, ep2_t *t, bn_t k) { + bn_t n, _k; + if (bn_is_zero(k)) { ep2_set_infty(r); return; } - ep2_set_infty(r); + bn_null(n); + bn_null(_k); - for (int i = 0; i < bn_bits(k); i++) { - if (bn_get_bit(k, i)) { - ep2_add(r, r, t[i]); + RLC_TRY { + bn_new(n); + bn_new(_k); + + ep2_curve_get_ord(n); + bn_mod(_k, k, n); + + ep2_set_infty(r); + for (int i = 0; i < bn_bits(_k); i++) { + if (bn_get_bit(_k, i)) { + ep2_add(r, r, t[i]); + } } - } - ep2_norm(r, r); - if (bn_sign(k) == RLC_NEG) { - ep2_neg(r, r); + ep2_norm(r, r); + if (bn_sign(_k) == RLC_NEG) { + ep2_neg(r, r); + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(n); + bn_free(_k); } } @@ -207,7 +194,7 @@ void ep2_mul_pre_combs(ep2_t *t, ep2_t p) { void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { int i, j, l, w, n0, p0, p1; - bn_t n; + bn_t n, _k; if (bn_is_zero(k)) { ep2_set_infty(r); @@ -215,15 +202,18 @@ void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { } bn_null(n); + bn_null(_k); RLC_TRY { bn_new(n); + bn_new(_k); ep2_curve_get_ord(n); l = bn_bits(n); l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); - n0 = bn_bits(k); + bn_mod(_k, k, n); + n0 = bn_bits(_k); p0 = (EP_DEPTH) * l - 1; @@ -231,7 +221,7 @@ void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { p1 = p0--; for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) { w = w << 1; - if (p1 < n0 && bn_get_bit(k, p1)) { + if (p1 < n0 && bn_get_bit(_k, p1)) { w = w | 1; } } @@ -244,7 +234,7 @@ void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { p1 = p0--; for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) { w = w << 1; - if (p1 < n0 && bn_get_bit(k, p1)) { + if (p1 < n0 && bn_get_bit(_k, p1)) { w = w | 1; } } @@ -253,7 +243,7 @@ void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { } } ep2_norm(r, r); - if (bn_sign(k) == RLC_NEG) { + if (bn_sign(_k) == RLC_NEG) { ep2_neg(r, r); } } @@ -262,6 +252,7 @@ void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { } RLC_FINALLY { bn_free(n); + bn_free(_k); } } @@ -320,7 +311,7 @@ void ep2_mul_pre_combd(ep2_t *t, ep2_t p) { void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { int i, j, d, e, w0, w1, n0, p0, p1; - bn_t n; + bn_t n, _k; if (bn_is_zero(k)) { ep2_set_infty(r); @@ -328,6 +319,7 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { } bn_null(n); + bn_null(_k); RLC_TRY { bn_new(n); @@ -338,7 +330,8 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1); ep2_set_infty(r); - n0 = bn_bits(k); + bn_mod(_k, k, n); + n0 = bn_bits(_k); p1 = (e - 1) + (EP_DEPTH - 1) * d; for (i = e - 1; i >= 0; i--) { @@ -348,7 +341,7 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { p0 = p1; for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) { w0 = w0 << 1; - if (p0 < n0 && bn_get_bit(k, p0)) { + if (p0 < n0 && bn_get_bit(_k, p0)) { w0 = w0 | 1; } } @@ -357,7 +350,7 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { p0 = p1-- + e; for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) { w1 = w1 << 1; - if (i + e < d && p0 < n0 && bn_get_bit(k, p0)) { + if (i + e < d && p0 < n0 && bn_get_bit(_k, p0)) { w1 = w1 | 1; } } @@ -366,7 +359,7 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { ep2_add(r, r, t[(1 << EP_DEPTH) + w1]); } ep2_norm(r, r); - if (bn_sign(k) == RLC_NEG) { + if (bn_sign(_k) == RLC_NEG) { ep2_neg(r, r); } } @@ -375,6 +368,7 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { } RLC_FINALLY { bn_free(n); + bn_free(_k); } } @@ -383,11 +377,33 @@ void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { #if EP_FIX == LWNAF || !defined(STRIP) void ep2_mul_pre_lwnaf(ep2_t *t, ep2_t p) { - ep2_mul_pre_ordin(t, p); + ep2_tab(t, p, EP_DEPTH); } void ep2_mul_fix_lwnaf(ep2_t r, ep2_t *t, bn_t k) { - ep2_mul_fix_ordin(r, t, k); + bn_t n, _k; + + if (bn_is_zero(k)) { + ep2_set_infty(r); + return; + } + + bn_null(n); + bn_null(_k); + + RLC_TRY { + bn_new(n); + bn_new(_k); + + ep2_curve_get_ord(n); + bn_mod(_k, k, n); + ep2_mul_fix_plain(r, t, _k); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(n); + bn_free(_k); + } } #endif diff --git a/contrib/relic/src/epx/relic_ep2_mul_sim.c b/contrib/relic/src/epx/relic_ep2_mul_sim.c index 11911ad5c..f4aa5c64b 100644 --- a/contrib/relic/src/epx/relic_ep2_mul_sim.c +++ b/contrib/relic/src/epx/relic_ep2_mul_sim.c @@ -40,146 +40,6 @@ #if defined(EP_ENDOM) -/** - * Recodes a scalar in subscalars according to Frobenius endomorphism. - * - * @param[out] _k - the recoded subscalars. - * @param[in] k - the scalar to recode. - */ -static void ep2_glv(bn_t _k[4], const bn_t k) { - int i, l; - bn_t n, u[4], v[4]; - - bn_null(n); - - RLC_TRY { - bn_new(n); - for (i = 0; i < 4; i++) { - bn_null(u[i]); - bn_null(v[i]); - bn_new(u[i]); - bn_new(v[i]); - } - - ep2_curve_get_ord(n); - - switch (ep_curve_is_pairf()) { - case EP_BN: - ep2_curve_get_vs(v); - - for (i = 0; i < 4; i++) { - bn_mul(v[i], v[i], k); - bn_div(v[i], v[i], n); - if (bn_sign(v[i]) == RLC_NEG) { - bn_add_dig(v[i], v[i], 1); - } - bn_zero(_k[i]); - } - - /* u0 = x + 1, u1 = 2x + 1, u2 = 2x, u3 = x - 1. */ - fp_prime_get_par(u[0]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[1], u[2], 1); - bn_sub_dig(u[3], u[0], 1); - bn_add_dig(u[0], u[0], 1); - bn_copy(_k[0], k); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[0], _k[0], n); - bn_sub(_k[0], _k[0], u[i]); - bn_mod(_k[0], _k[0], n); - } - - /* u0 = x, u1 = -x, u2 = 2x + 1, u3 = 4x + 2. */ - fp_prime_get_par(u[0]); - bn_neg(u[1], u[0]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[2], u[2], 1); - bn_dbl(u[3], u[2]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[1], _k[1], n); - bn_sub(_k[1], _k[1], u[i]); - bn_mod(_k[1], _k[1], n); - } - - /* u0 = x, u1 = -(x + 1), u2 = 2x + 1, u3 = -(2x - 1). */ - fp_prime_get_par(u[0]); - bn_add_dig(u[1], u[0], 1); - bn_neg(u[1], u[1]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[2], u[2], 1); - bn_sub_dig(u[3], u[2], 2); - bn_neg(u[3], u[3]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[2], _k[2], n); - bn_sub(_k[2], _k[2], u[i]); - bn_mod(_k[2], _k[2], n); - } - - /* u0 = -2x, u1 = -x, u2 = 2x + 1, u3 = x - 1. */ - fp_prime_get_par(u[1]); - bn_dbl(u[0], u[1]); - bn_neg(u[0], u[0]); - bn_dbl(u[2], u[1]); - bn_add_dig(u[2], u[2], 1); - bn_sub_dig(u[3], u[1], 1); - bn_neg(u[1], u[1]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_k[3], _k[3], n); - bn_sub(_k[3], _k[3], u[i]); - bn_mod(_k[3], _k[3], n); - } - - for (i = 0; i < 4; i++) { - l = bn_bits(_k[i]); - bn_sub(_k[i], n, _k[i]); - if (bn_bits(_k[i]) > l) { - bn_sub(_k[i], _k[i], n); - _k[i]->sign = RLC_POS; - } else { - _k[i]->sign = RLC_NEG; - } - } - break; - default: - bn_abs(v[0], k); - fp_prime_get_par(u[0]); - bn_copy(u[1], u[0]); - if (bn_sign(u[0]) == RLC_NEG) { - bn_neg(u[0], u[0]); - } - - for (i = 0; i < 4; i++) { - bn_mod(_k[i], v[0], u[0]); - bn_div(v[0], v[0], u[0]); - if ((bn_sign(u[1]) == RLC_NEG) && (i % 2 != 0)) { - bn_neg(_k[i], _k[i]); - } - if (bn_sign(k) == RLC_NEG) { - bn_neg(_k[i], _k[i]); - } - } - - break; - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - bn_free(n); - for (i = 0; i < 4; i++) { - bn_free(u[i]); - bn_free(v[i]); - } - } -} - /** * Multiplies and adds two prime elliptic curve points simultaneously, * optionally choosing the first point as the generator depending on an optional @@ -194,10 +54,15 @@ static void ep2_glv(bn_t _k[4], const bn_t k) { */ static void ep2_mul_sim_endom(ep2_t r, ep2_t p, const bn_t k, ep2_t q, const bn_t m) { int i, j, l; - bn_t _k[4], _m[4]; + bn_t n, u, _k[4], _m[4]; ep2_t _p[4], _q[4]; + bn_null(n); + bn_null(u); + RLC_TRY { + bn_new(n); + bn_new(u); for (i = 0; i < 4; i++) { bn_null(_k[i]); bn_null(_m[i]); @@ -209,8 +74,10 @@ static void ep2_mul_sim_endom(ep2_t r, ep2_t p, const bn_t k, ep2_t q, const bn_ ep2_new(_q[i]); } - ep2_glv(_k, k); - ep2_glv(_m, m); + ep2_curve_get_ord(n); + fp_prime_get_par(u); + bn_rec_frb(_k, 4, k, u, n, ep_curve_is_pairf() == EP_B12); + bn_rec_frb(_m, 4, m, u, n, ep_curve_is_pairf() == EP_B12); ep2_norm(_p[0], p); ep2_frb(_p[1], _p[0], 1); @@ -253,6 +120,8 @@ static void ep2_mul_sim_endom(ep2_t r, ep2_t p, const bn_t k, ep2_t q, const bn_ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(n); + bn_free(u); for (i = 0; i < 4; i++) { bn_free(_k[i]); bn_free(_m[i]); @@ -315,13 +184,6 @@ static void ep2_mul_sim_plain(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m, l = RLC_MAX(l0, l1); _k = naf0 + l - 1; _m = naf1 + l - 1; - for (i = l0; i < l; i++) { - naf0[i] = 0; - } - for (i = l1; i < l; i++) { - naf1[i] = 0; - } - if (bn_sign(k) == RLC_NEG) { for (i = 0; i < l0; i++) { naf0[i] = -naf0[i]; @@ -407,11 +269,13 @@ void ep2_mul_sim_trick(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { ep2_t t0[1 << (EP_WIDTH / 2)]; ep2_t t1[1 << (EP_WIDTH / 2)]; ep2_t t[1 << EP_WIDTH]; - bn_t n; + bn_t n, _k, _m; int l0, l1, w = EP_WIDTH / 2; uint8_t w0[2 * RLC_FP_BITS], w1[2 * RLC_FP_BITS]; bn_null(n); + bn_null(_k); + bn_null(_m); if (bn_is_zero(k) || ep2_is_infty(p)) { ep2_mul(r, q, m); @@ -424,8 +288,12 @@ void ep2_mul_sim_trick(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { RLC_TRY { bn_new(n); + bn_new(_k); + bn_new(_m); ep2_curve_get_ord(n); + bn_mod(_k, k, n); + bn_mod(_m, m, n); for (int i = 0; i < (1 << w); i++) { ep2_null(t0[i]); @@ -490,6 +358,8 @@ void ep2_mul_sim_trick(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { } RLC_FINALLY { bn_free(n); + bn_free(_k); + bn_free(_m); for (int i = 0; i < (1 << w); i++) { ep2_free(t0[i]); ep2_free(t1[i]); @@ -504,6 +374,9 @@ void ep2_mul_sim_trick(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { #if EP_SIM == INTER || !defined(STRIP) void ep2_mul_sim_inter(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { + int flag = 0; + bn_t n, _k, _m; + if (bn_is_zero(k) || ep2_is_infty(p)) { ep2_mul(r, q, m); return; @@ -513,20 +386,41 @@ void ep2_mul_sim_inter(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { return; } + bn_null(n); + bn_null(_k); + bn_null(_m); + + RLC_TRY { + bn_new(n); + bn_new(_k); + bn_new(_m); + + /* Handle this here to reduce complexity of static functions. */ + ep2_curve_get_ord(n); + bn_mod(_k, k, n); + bn_mod(_m, m, n); + #if defined(EP_ENDOM) - if (ep_curve_is_endom()) { - if (ep_curve_opt_a() == RLC_ZERO) { - ep2_mul_sim_endom(r, p, k, q, m); - } else { - ep2_mul_sim_plain(r, p, k, q, m, NULL); + if (ep_curve_is_endom()) { + ep2_mul_sim_endom(r, p, _k, q, _m); + flag = 1; } - return; - } #endif -#if defined(EP_PLAIN) - ep2_mul_sim_plain(r, p, k, q, m, NULL); +#if defined(EP_PLAIN) || defined(EP_SUPER) + if (!flag) { + ep2_mul_sim_plain(r, p, _k, q, _m, NULL); + } #endif + (void)flag; + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(_k); + bn_free(_m); + } } #endif @@ -534,9 +428,10 @@ void ep2_mul_sim_inter(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { #if EP_SIM == JOINT || !defined(STRIP) void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { + bn_t n, _k, _m; ep2_t t[5]; int i, l, u_i, offset; - int8_t jsf[4 * (RLC_FP_BITS + 1)]; + int8_t jsf[2 * (RLC_FP_BITS + 1)]; if (bn_is_zero(k) || ep2_is_infty(p)) { ep2_mul(r, q, m); @@ -547,19 +442,30 @@ void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { return; } + bn_null(n); + bn_null(_k); + bn_null(_m); + RLC_TRY { + bn_new(n); + bn_new(_k); + bn_new(_m); for (i = 0; i < 5; i++) { ep2_null(t[i]); ep2_new(t[i]); } + ep2_curve_get_ord(n); + bn_mod(_k, k, n); + bn_mod(_m, m, n); + ep2_set_infty(t[0]); ep2_copy(t[1], q); - if (bn_sign(m) == RLC_NEG) { + if (bn_sign(_m) == RLC_NEG) { ep2_neg(t[1], t[1]); } ep2_copy(t[2], p); - if (bn_sign(k) == RLC_NEG) { + if (bn_sign(_k) == RLC_NEG) { ep2_neg(t[2], t[2]); } ep2_add(t[3], t[2], t[1]); @@ -568,12 +474,12 @@ void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { ep2_norm_sim(t + 3, t + 3, 2); #endif - l = 4 * (RLC_FP_BITS + 1); - bn_rec_jsf(jsf, &l, k, m); + l = 2 * (RLC_FP_BITS + 1); + bn_rec_jsf(jsf, &l, _k, _m); ep2_set_infty(r); - offset = RLC_MAX(bn_bits(k), bn_bits(m)) + 1; + offset = RLC_MAX(bn_bits(_k), bn_bits(_m)) + 1; for (i = l - 1; i >= 0; i--) { ep2_dbl(r, r); if (jsf[i] != 0 && jsf[i] == -jsf[i + offset]) { @@ -598,6 +504,9 @@ void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(n); + bn_free(_k); + bn_free(_m); for (i = 0; i < 5; i++) { ep2_free(t[i]); } @@ -607,9 +516,8 @@ void ep2_mul_sim_joint(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t m) { #endif void ep2_mul_sim_gen(ep2_t r, bn_t k, ep2_t q, bn_t m) { - ep2_t gen; - - ep2_null(gen); + ep2_t g; + bn_t n, _k, _m; if (bn_is_zero(k)) { ep2_mul(r, q, m); @@ -620,21 +528,55 @@ void ep2_mul_sim_gen(ep2_t r, bn_t k, ep2_t q, bn_t m) { return; } + ep2_null(g); + bn_null(n); + bn_null(_k); + bn_null(_m); + RLC_TRY { - ep2_new(gen); + ep2_new(g); + bn_new(n); + bn_new(_k); + bn_new(_m); + + ep2_curve_get_gen(g); + ep2_curve_get_ord(n); + + bn_mod(_k, k, n); + bn_mod(_m, m, n); - ep2_curve_get_gen(gen); -#if EP_FIX == LWNAF && defined(EP_PRECO) - ep2_mul_sim_plain(r, gen, k, q, m, ep2_curve_get_tab()); +#if defined(EP_ENDOM) +#if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO) + if (ep_curve_is_endom()) { + ep2_mul_sim_endom(r, g, _k, q, _m, ep2_curve_get_tab()); + } #else - ep2_mul_sim(r, gen, k, q, m); + if (ep_curve_is_endom()) { + ep2_mul_sim(r, g, _k, q, _m); + } +#endif +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) +#if EP_SIM == INTER && EP_FIX == LWNAF && defined(EP_PRECO) + if (!ep_curve_is_endom()) { + ep2_mul_sim_plain(r, g, _k, q, _m, ep2_curve_get_tab()); + } +#else + if (!ep_curve_is_endom()) { + ep2_mul_sim(r, g, _k, q, _m); + } +#endif #endif } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { - ep2_free(gen); + ep2_free(g); + bn_free(n); + bn_free(_k); + bn_free(_m); } } @@ -674,14 +616,27 @@ void ep2_mul_sim_dig(ep2_t r, ep2_t p[], dig_t k[], int len) { void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { const int len = RLC_FP_BITS + 1; - int i, j, m, l, *_l = RLC_ALLOCA(int, 4 * n); - bn_t _k[4]; - int8_t *naf = RLC_ALLOCA(int8_t, 4 * n * len); + int i, j, m, l, _l[4]; + bn_t _k[4], q, x; + int8_t ptr, *naf = RLC_ALLOCA(int8_t, 4 * n * len); + + if (n == 0) { + ep2_set_infty(r); + return; + } + + bn_null(q); + bn_null(x); if (n <= 10) { ep2_t *_p = RLC_ALLOCA(ep2_t, 4 * n); RLC_TRY { + if (naf == NULL || _p == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + bn_new(q); + bn_new(x); for (j = 0; j < 4; j++) { bn_null(_k[j]); bn_new(_k[j]); @@ -691,31 +646,24 @@ void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { } } - for (int i = 0; i < n; i++) { + l = 0; + ep2_curve_get_ord(q); + fp_prime_get_par(x); + for (i = 0; i < n; i++) { ep2_norm(_p[4*i], p[i]); ep2_frb(_p[4*i + 1], _p[4*i], 1); ep2_frb(_p[4*i + 2], _p[4*i + 1], 1); ep2_frb(_p[4*i + 3], _p[4*i + 2], 1); - } - l = 0; - for (i = 0; i < n; i++) { - ep2_glv(_k, k[i]); + bn_mod(_k[0], k[i], q); + bn_rec_frb(_k, 4, _k[0], x, q, ep_curve_is_pairf() == EP_B12); for (j = 0; j < 4; j++) { - _l[4*i + j] = len; - bn_rec_naf(&naf[(4*i + j)*len], &_l[4*i + j], _k[j], 2); + _l[j] = len; + bn_rec_naf(&naf[(4*i + j)*len], &_l[j], _k[j], 2); if (bn_sign(_k[j]) == RLC_NEG) { ep2_neg(_p[4*i + j], _p[4*i + j]); } - l = RLC_MAX(l, _l[4*i + j]); - } - } - - for (i = 0; i < n; i++) { - for (j = 0; j < 4; j++) { - for (m = _l[4*i + j]; m < l; m++) { - naf[(4*i + j)*len + m] = 0; - } + l = RLC_MAX(l, _l[j]); } } @@ -739,26 +687,32 @@ void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(q); + bn_free(x); for (j = 0; j < 4; j++) { bn_free(_k[j]); for (i = 0; i < n; i++) { ep2_free(_p[4*i + j]); } } - RLC_FREE(_l); RLC_FREE(_p); RLC_FREE(naf); } } else { const int w = RLC_MAX(2, util_bits_dig(n) - 2), c = (1 << (w - 2)); ep2_t s, t, u, v, *_p = RLC_ALLOCA(ep2_t, 4 * c); - int8_t ptr; + + ep2_null(s); + ep2_null(t); + ep2_null(u); + ep2_null(v); RLC_TRY { - ep2_null(s); - ep2_null(t); - ep2_null(u); - ep2_null(v); + if (naf == NULL || _p == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + bn_new(q); + bn_new(x); ep2_new(s); ep2_new(t); ep2_new(u); @@ -774,20 +728,20 @@ void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { } l = 0; + ep2_curve_get_ord(q); + fp_prime_get_par(x); for (i = 0; i < n; i++) { - ep2_glv(_k, k[i]); + bn_mod(_k[0], k[i], q); + bn_rec_frb(_k, 4, _k[0], x, q, ep_curve_is_pairf() == EP_B12); for (j = 0; j < 4; j++) { - _l[4*i + j] = len; - bn_rec_naf(&naf[(4*i + j)*len], &_l[4*i + j], _k[j], w); - l = RLC_MAX(l, _l[4*i + j]); - } - } - - for (i = 0; i < n; i++) { - for (j = 0; j < 4; j++) { - for (m = _l[4*i + j]; m < l; m++) { - naf[(4*i + j)*len + m] = 0; + _l[j] = len; + bn_rec_naf(&naf[(4*i + j)*len], &_l[j], _k[j], w); + if (bn_sign(_k[j]) == RLC_NEG) { + for (m = 0; m < _l[j]; m++) { + naf[(4*i + j)*len + m] = -naf[(4*i + j)*len + m]; + } } + l = RLC_MAX(l, _l[j]); } } @@ -802,9 +756,6 @@ void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { ptr = -ptr; ep2_neg(t, t); } - if (bn_sign(_k[m]) == RLC_NEG) { - ep2_neg(t, t); - } ep2_add(_p[m*c + (ptr >> 1)], _p[m*c + (ptr >> 1)], t); } } @@ -834,6 +785,8 @@ void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(q); + bn_free(x); ep2_free(s); ep2_free(t); ep2_free(u); @@ -844,7 +797,6 @@ void ep2_mul_sim_lot(ep2_t r, ep2_t p[], const bn_t k[], int n) { ep2_free(_p[i*c + j]); } } - RLC_FREE(_l); RLC_FREE(_p); RLC_FREE(naf); } diff --git a/contrib/relic/src/epx/relic_ep2_pck.c b/contrib/relic/src/epx/relic_ep2_pck.c index 0aab817f3..09282756b 100644 --- a/contrib/relic/src/epx/relic_ep2_pck.c +++ b/contrib/relic/src/epx/relic_ep2_pck.c @@ -27,7 +27,7 @@ * Implementation of point compression on prime elliptic curves over quadratic * extensions. * - * @ingroup ep + * @ingroup epx */ #include "relic_core.h" diff --git a/contrib/relic/src/epx/relic_ep2_util.c b/contrib/relic/src/epx/relic_ep2_util.c index 571b26a8b..8f1490b37 100644 --- a/contrib/relic/src/epx/relic_ep2_util.c +++ b/contrib/relic/src/epx/relic_ep2_util.c @@ -85,17 +85,17 @@ void ep2_blind(ep2_t r, ep2_t p) { RLC_TRY { fp2_new(rand); + fp2_rand(rand); #if EP_ADD == BASIC (void)rand; ep2_copy(r, p); -#elif EP_ADD == PROJC - fp2_rand(rand); +#else fp2_mul(r->z, p->z, rand); fp2_mul(r->y, p->y, rand); fp2_sqr(rand, rand); fp2_mul(r->x, r->x, rand); fp2_mul(r->y, r->y, rand); - r->coord = PROJC; + r->coord = EP_ADD; #endif } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -260,8 +260,7 @@ void ep2_read_bin(ep2_t a, const uint8_t *bin, int len) { } a->coord = BASIC; - fp_set_dig(a->z[0], 1); - fp_zero(a->z[1]); + fp2_set_dig(a->z, 1); fp2_read_bin(a->x, bin + 1, 2 * RLC_FP_BYTES); if (len == 2 * RLC_FP_BYTES + 1) { switch(bin[0]) { @@ -288,6 +287,10 @@ void ep2_read_bin(ep2_t a, const uint8_t *bin, int len) { return; } } + + if (!ep2_on_curve(a)) { + RLC_THROW(ERR_NO_VALID); + } } void ep2_write_bin(uint8_t *bin, int len, ep2_t a, int pack) { @@ -295,12 +298,13 @@ void ep2_write_bin(uint8_t *bin, int len, ep2_t a, int pack) { ep2_null(t); + memset(bin, 0, len); + if (ep2_is_infty(a)) { if (len < 1) { RLC_THROW(ERR_NO_BUFFER); return; } else { - bin[0] = 0; return; } } diff --git a/contrib/relic/src/epx/relic_ep4_add.c b/contrib/relic/src/epx/relic_ep4_add.c new file mode 100644 index 000000000..af731a5ea --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_add.c @@ -0,0 +1,434 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of addition on prime elliptic curves over quartic + * extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +#if EP_ADD == BASIC || !defined(STRIP) + +/** + * Adds two points represented in affine coordinates on an ordinary prime + * elliptic curve. + * + * @param r - the result. + * @param s - the resulting slope. + * @param p - the first point to add. + * @param q - the second point to add. + */ +static void ep4_add_basic_imp(ep4_t r, fp4_t s, ep4_t p, ep4_t q) { + fp4_t t0, t1, t2; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + + /* t0 = x2 - x1. */ + fp4_sub(t0, q->x, p->x); + /* t1 = y2 - y1. */ + fp4_sub(t1, q->y, p->y); + + /* If t0 is zero. */ + if (fp4_is_zero(t0)) { + if (fp4_is_zero(t1)) { + /* If t1 is zero, q = p, should have doubled. */ + ep4_dbl_slp_basic(r, s, p); + } else { + /* If t1 is not zero and t0 is zero, q = -p and r = infty. */ + ep4_set_infty(r); + } + } else { + /* t2 = 1/(x2 - x1). */ + fp4_inv(t2, t0); + /* t2 = lambda = (y2 - y1)/(x2 - x1). */ + fp4_mul(t2, t1, t2); + + /* x3 = lambda^2 - x2 - x1. */ + fp4_sqr(t1, t2); + fp4_sub(t0, t1, p->x); + fp4_sub(t0, t0, q->x); + + /* y3 = lambda * (x1 - x3) - y1. */ + fp4_sub(t1, p->x, t0); + fp4_mul(t1, t2, t1); + fp4_sub(r->y, t1, p->y); + + fp4_copy(r->x, t0); + fp4_copy(r->z, p->z); + + if (s != NULL) { + fp4_copy(s, t2); + } + + r->coord = BASIC; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + } +} + +#endif /* EP_ADD == BASIC */ + +#if EP_ADD == PROJC || !defined(STRIP) + +#if defined(EP_MIXED) || !defined(STRIP) + +/** + * Adds a point represented in affine coordinates to a point represented in + * projective coordinates. + * + * @param r - the result. + * @param s - the slope. + * @param p - the affine point. + * @param q - the projective point. + */ +static void ep4_add_projc_mix(ep4_t r, ep4_t p, ep4_t q) { + fp4_t t0, t1, t2, t3, t4, t5, t6; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + fp4_null(t5); + fp4_null(t6); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + fp4_new(t5); + fp4_new(t6); + + if (p->coord != BASIC) { + /* t0 = z1^2. */ + fp4_sqr(t0, p->z); + + /* t3 = U2 = x2 * z1^2. */ + fp4_mul(t3, q->x, t0); + + /* t1 = S2 = y2 * z1^3. */ + fp4_mul(t1, t0, p->z); + fp4_mul(t1, t1, q->y); + + /* t3 = H = U2 - x1. */ + fp4_sub(t3, t3, p->x); + + /* t1 = R = 2 * (S2 - y1). */ + fp4_sub(t1, t1, p->y); + } else { + /* H = x2 - x1. */ + fp4_sub(t3, q->x, p->x); + + /* t1 = R = 2 * (y2 - y1). */ + fp4_sub(t1, q->y, p->y); + } + + /* t2 = HH = H^2. */ + fp4_sqr(t2, t3); + + /* If E is zero. */ + if (fp4_is_zero(t3)) { + if (fp4_is_zero(t1)) { + /* If I is zero, p = q, should have doubled. */ + ep4_dbl_projc(r, p); + } else { + /* If I is not zero, q = -p, r = infinity. */ + ep4_set_infty(r); + } + } else { + /* t5 = J = H * HH. */ + fp4_mul(t5, t3, t2); + + /* t4 = V = x1 * HH. */ + fp4_mul(t4, p->x, t2); + + /* x3 = R^2 - J - 2 * V. */ + fp4_sqr(r->x, t1); + fp4_sub(r->x, r->x, t5); + fp4_dbl(t6, t4); + fp4_sub(r->x, r->x, t6); + + /* y3 = R * (V - x3) - Y1 * J. */ + fp4_sub(t4, t4, r->x); + fp4_mul(t4, t4, t1); + fp4_mul(t1, p->y, t5); + fp4_sub(r->y, t4, t1); + + if (p->coord != BASIC) { + /* z3 = z1 * H. */ + fp4_mul(r->z, p->z, t3); + } else { + /* z3 = H. */ + fp4_copy(r->z, t3); + } + } + r->coord = PROJC; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + fp4_free(t5); + fp4_free(t6); + } +} + +#endif + +/** + * Adds two points represented in projective coordinates on an ordinary prime + * elliptic curve. + * + * @param r - the result. + * @param p - the first point to add. + * @param q - the second point to add. + */ +static void ep4_add_projc_imp(ep4_t r, ep4_t p, ep4_t q) { +#if defined(EP_MIXED) && defined(STRIP) + ep4_add_projc_mix(r, p, q); +#else /* General addition. */ + fp4_t t0, t1, t2, t3, t4, t5, t6; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + fp4_null(t5); + fp4_null(t6); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + fp4_new(t5); + fp4_new(t6); + + if (q->coord == BASIC) { + ep4_add_projc_mix(r, p, q); + } else { + /* t0 = z1^2. */ + fp4_sqr(t0, p->z); + + /* t1 = z2^2. */ + fp4_sqr(t1, q->z); + + /* t2 = U1 = x1 * z2^2. */ + fp4_mul(t2, p->x, t1); + + /* t3 = U2 = x2 * z1^2. */ + fp4_mul(t3, q->x, t0); + + /* t6 = z1^2 + z2^2. */ + fp4_add(t6, t0, t1); + + /* t0 = S2 = y2 * z1^3. */ + fp4_mul(t0, t0, p->z); + fp4_mul(t0, t0, q->y); + + /* t1 = S1 = y1 * z2^3. */ + fp4_mul(t1, t1, q->z); + fp4_mul(t1, t1, p->y); + + /* t3 = H = U2 - U1. */ + fp4_sub(t3, t3, t2); + + /* t0 = R = 2 * (S2 - S1). */ + fp4_sub(t0, t0, t1); + + fp4_dbl(t0, t0); + + /* If E is zero. */ + if (fp4_is_zero(t3)) { + if (fp4_is_zero(t0)) { + /* If I is zero, p = q, should have doubled. */ + ep4_dbl_projc(r, p); + } else { + /* If I is not zero, q = -p, r = infinity. */ + ep4_set_infty(r); + } + } else { + /* t4 = I = (2*H)^2. */ + fp4_dbl(t4, t3); + fp4_sqr(t4, t4); + + /* t5 = J = H * I. */ + fp4_mul(t5, t3, t4); + + /* t4 = V = U1 * I. */ + fp4_mul(t4, t2, t4); + + /* x3 = R^2 - J - 2 * V. */ + fp4_sqr(r->x, t0); + fp4_sub(r->x, r->x, t5); + fp4_dbl(t2, t4); + fp4_sub(r->x, r->x, t2); + + /* y3 = R * (V - x3) - 2 * S1 * J. */ + fp4_sub(t4, t4, r->x); + fp4_mul(t4, t4, t0); + fp4_mul(t1, t1, t5); + fp4_dbl(t1, t1); + fp4_sub(r->y, t4, t1); + + /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ + fp4_add(r->z, p->z, q->z); + fp4_sqr(r->z, r->z); + fp4_sub(r->z, r->z, t6); + fp4_mul(r->z, r->z, t3); + } + } + r->coord = PROJC; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + fp4_free(t5); + fp4_free(t6); + } +#endif +} + +#endif /* EP_ADD == PROJC */ + +/*============================================================================*/ + /* Public definitions */ +/*============================================================================*/ + +#if EP_ADD == BASIC || !defined(STRIP) + +void ep4_add_basic(ep4_t r, ep4_t p, ep4_t q) { + if (ep4_is_infty(p)) { + ep4_copy(r, q); + return; + } + + if (ep4_is_infty(q)) { + ep4_copy(r, p); + return; + } + + ep4_add_basic_imp(r, NULL, p, q); +} + +void ep4_add_slp_basic(ep4_t r, fp4_t s, ep4_t p, ep4_t q) { + if (ep4_is_infty(p)) { + ep4_copy(r, q); + return; + } + + if (ep4_is_infty(q)) { + ep4_copy(r, p); + return; + } + + ep4_add_basic_imp(r, s, p, q); +} + +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + +void ep4_add_projc(ep4_t r, ep4_t p, ep4_t q) { + if (ep4_is_infty(p)) { + ep4_copy(r, q); + return; + } + + if (ep4_is_infty(q)) { + ep4_copy(r, p); + return; + } + + if (p == q) { + /* TODO: This is a quick hack. Should we fix this? */ + ep4_dbl(r, p); + return; + } + + ep4_add_projc_imp(r, p, q); +} + +#endif + +void ep4_sub(ep4_t r, ep4_t p, ep4_t q) { + ep4_t t; + + ep4_null(t); + + if (p == q) { + ep4_set_infty(r); + return; + } + + RLC_TRY { + ep4_new(t); + + ep4_neg(t, q); + ep4_add(r, p, t); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(t); + } +} diff --git a/contrib/relic/src/epx/relic_ep4_cmp.c b/contrib/relic/src/epx/relic_ep4_cmp.c new file mode 100644 index 000000000..3d12fc327 --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_cmp.c @@ -0,0 +1,82 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of utilities for prime elliptic curves over quadratic + * extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int ep4_cmp(ep4_t p, ep4_t q) { + ep4_t r, s; + int result = RLC_NE; + + if (ep4_is_infty(p) && ep4_is_infty(q)) { + return RLC_EQ; + } + + ep4_null(r); + ep4_null(s); + + RLC_TRY { + ep4_new(r); + ep4_new(s); + + if ((p->coord != BASIC) && (q->coord != BASIC)) { + /* If the two points are not normalized, it is faster to compare + * x1 * z2^2 == x2 * z1^2 and y1 * z2^3 == y2 * z1^3. */ + fp4_sqr(r->z, p->z); + fp4_sqr(s->z, q->z); + fp4_mul(r->x, p->x, s->z); + fp4_mul(s->x, q->x, r->z); + fp4_mul(r->z, r->z, p->z); + fp4_mul(s->z, s->z, q->z); + fp4_mul(r->y, p->y, s->z); + fp4_mul(s->y, q->y, r->z); + } else { + ep4_norm(r, p); + ep4_norm(s, q); + } + + if ((fp4_cmp(r->x, s->x) == RLC_EQ) && + (fp4_cmp(r->y, s->y) == RLC_EQ)) { + result = RLC_EQ; + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + ep4_free(r); + ep4_free(s); + } + + return result; +} diff --git a/contrib/relic/src/epx/relic_ep4_curve.c b/contrib/relic/src/epx/relic_ep4_curve.c new file mode 100644 index 000000000..d70cc792a --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_curve.c @@ -0,0 +1,377 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of configuration of prime elliptic curves over quartic + * extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +/* See ep/relic_ep_param.c for discussion of MAP_U parameters. */ + +#if defined(EP_ENDOM) && FP_PRIME == 509 +/** @{ */ +#define B24_P509_A0 "0" +#define B24_P509_A1 "0" +#define B24_P509_A2 "0" +#define B24_P509_A3 "0" +#define B24_P509_B0 "0" +#define B24_P509_B1 "0" +#define B24_P509_B2 "AAAAB7FFF9CE54DFE76F95A7CE0767B65C56424AE8C3F4619750081F008485DB13742DFBE0C507867E5AE3038DD69E97731DE83B746C980509E88C6DC5FE956" +#define B24_P509_B3 "AAAAB7FFF9CE54DFE76F95A7CE0767B65C56424AE8C3F4619750081F008485DB13742DFBE0C507867E5AE3038DD69E97731DE83B746C980509E88C6DC5FE955" +#define B24_P509_X0 "4D5AF70D2E605D1691DE7667FF1096AF4537749FD200277E1BC502847F63F4BC2F000FC81571F6E282FD46B96045CD611159ED554AFA95B2B1800A74F6A97C0" +#define B24_P509_X1 "EA0D1E6A2105587ED20E9CA255A777AC78D0A24AEB118B1CE4D1F213BE42F7FFD3F3F5F60F06F902FEE405DF84143D533006D7383C25A7F7C26656440A80A0B" +#define B24_P509_X2 "10E955FAFCA0C3C16D9DA9754859EAF918518C1A3FD0D14F427302CDE750224AD9E337CA12D3824B9E5E1668F94F56A4C2D935C6841C65FF4CA89E62C6A88D34" +#define B24_P509_X3 "A9A981033A3844468D815A18B921C9F7C2B152372F240EAC4848A942FEAA4019B086104AE4F86C929F5B9064B4FE917A327279CEDCE02962FD3E971F9D00CCA" +#define B24_P509_Y0 "C45C4179589584F8D1146550C117E3B452B7789170B7E7C0BEB1E417B5E32845CC1810760585AE0FE07762D94774A311932C100276C7A2EA4304EF7FBAA89F" +#define B24_P509_Y1 "20315B1CE6AEE44F7ADCAE2F0B178DF7574F91380DB5E4A27281D02CC47A24618F995ACC29E611D7BBCE63E8A2CBD783256A1799FFA2A5D061D6872962CBAD" +#define B24_P509_Y2 "20DEE7CA8DF5A616A014D78C0BCC69491116C715DDF5416C52B8A1833F8E4974255FBCCC5C6288DCA9B7CB2F4BB58525AB13D2225590A4A69955A859D36BF67" +#define B24_P509_Y3 "5CD7D6B0C7890DC487A34BE4976767DE0C20BEB43A0EE741A5ED21021EBE5BDC42281008E19C44497E13A38165A36019235BDF7A48E76B6BA79D527024D227C" +#define B24_P509_R "100000FFFF870FF91CE195DB5B6F3EBD1E08C94C9E193B724ED58B907FF7C311A80D7CABC647746AE3ECB627C943998457FE001" +#define B24_P509_H "32916E9E0188E2252DA44F42F6DC0E90A66E8C7AFA49D50688A07F362BA18A01F6D9317009D55DAF8CFA9159E35E2736DA6417B31C8550DFC6CD766340D92AB85D629676E78E12D5E76AB9FAC536661EEA6615242264E5F6B46EBA0F95191CD226B0CB144CEC686A846DE323CBE0244A3B6E5FFE49BD01599F13AD869FF3DA2E5551FD9C2D885EF8FB95EB7FFD5460EC84FA36A569BCB5BBBC5A21B025CECEEAD08540C0ACCB87D9136ECB9C2CEDC2D465831D76AC3551EE87BCA06B751C18699A1424FF71E791EB953FA79" +/** @} */ +#endif + +/** + * Assigns a set of ordinary elliptic curve parameters. + * + * @param[in] CURVE - the curve parameters to assign. + */ +#define ASSIGN(CURVE) \ + RLC_GET(str, CURVE##_A0, sizeof(CURVE##_A0)); \ + fp_read_str(a[0][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_A1, sizeof(CURVE##_A1)); \ + fp_read_str(a[0][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_A2, sizeof(CURVE##_A2)); \ + fp_read_str(a[1][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_A3, sizeof(CURVE##_A3)); \ + fp_read_str(a[1][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_B0, sizeof(CURVE##_B0)); \ + fp_read_str(b[0][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_B1, sizeof(CURVE##_B1)); \ + fp_read_str(b[0][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_B2, sizeof(CURVE##_B2)); \ + fp_read_str(b[1][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_B3, sizeof(CURVE##_B3)); \ + fp_read_str(b[1][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_X0, sizeof(CURVE##_X0)); \ + fp_read_str(g->x[0][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_X1, sizeof(CURVE##_X1)); \ + fp_read_str(g->x[0][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_X2, sizeof(CURVE##_X2)); \ + fp_read_str(g->x[1][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_X3, sizeof(CURVE##_X3)); \ + fp_read_str(g->x[1][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_Y0, sizeof(CURVE##_Y0)); \ + fp_read_str(g->y[0][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_Y1, sizeof(CURVE##_Y1)); \ + fp_read_str(g->y[0][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_Y2, sizeof(CURVE##_Y2)); \ + fp_read_str(g->y[1][0], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_Y3, sizeof(CURVE##_Y3)); \ + fp_read_str(g->y[1][1], str, strlen(str), 16); \ + RLC_GET(str, CURVE##_R, sizeof(CURVE##_R)); \ + bn_read_str(r, str, strlen(str), 16); \ + RLC_GET(str, CURVE##_H, sizeof(CURVE##_H)); \ + bn_read_str(h, str, strlen(str), 16); \ + +/** + * Detects an optimization based on the curve coefficients. + */ +static void detect_opt(int *opt, fp4_t a) { + fp4_t t; + fp4_null(t); + + RLC_TRY { + fp4_new(t); + fp4_set_dig(t, 3); + fp4_neg(t, t); + + if (fp4_cmp(a, t) == RLC_EQ) { + *opt = RLC_MIN3; + } else if (fp4_is_zero(a)) { + *opt = RLC_ZERO; + } else if (fp4_cmp_dig(a, 1) == RLC_EQ) { + *opt = RLC_ONE; + } else if (fp4_cmp_dig(a, 2) == RLC_EQ) { + *opt = RLC_TWO; + } else if ((fp_bits(a[0][0]) <= RLC_DIG) && fp_is_zero(a[0][1]) && + fp2_is_zero(a[1])) { + *opt = RLC_TINY; + } else { + *opt = RLC_HUGE; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t); + } +} + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_curve_init(void) { + ctx_t *ctx = core_get(); + +#ifdef EP_PRECO + for (int i = 0; i < RLC_EP_TABLE; i++) { + ctx->ep4_ptr[i] = &(ctx->ep4_pre[i]); + } +#endif + +#if ALLOC == DYNAMIC + ep4_new(ctx->ep4_g); + fp4_new(ctx->ep4_a); + fp4_new(ctx->ep4_b); +#endif + +#ifdef EP_PRECO +#if ALLOC == DYNAMIC + for (int i = 0; i < RLC_EP_TABLE; i++) { + fp4_new(ctx->ep4_pre[i].x); + fp4_new(ctx->ep4_pre[i].y); + fp4_new(ctx->ep4_pre[i].z); + } +#endif +#endif + ep4_set_infty(ctx->ep4_g); + bn_make(&(ctx->ep4_r), RLC_FP_DIGS); + bn_make(&(ctx->ep4_h), RLC_FP_DIGS); +} + +void ep4_curve_clean(void) { + ctx_t *ctx = core_get(); + if (ctx != NULL) { +#ifdef EP_PRECO + for (int i = 0; i < RLC_EP_TABLE; i++) { + fp4_free(ctx->ep4_pre[i].x); + fp4_free(ctx->ep4_pre[i].y); + fp4_free(ctx->ep4_pre[i].z); + } +#endif + bn_clean(&(ctx->ep4_r)); + bn_clean(&(ctx->ep4_h)); + ep4_free(ctx->ep4_g); + fp4_free(ctx->ep4_a); + fp4_free(ctx->ep4_b); + } +} + +int ep4_curve_opt_a(void) { + return core_get()->ep4_opt_a; +} + +int ep4_curve_opt_b(void) { + return core_get()->ep4_opt_b; +} + +int ep4_curve_is_twist(void) { + return core_get()->ep4_is_twist; +} + +void ep4_curve_get_gen(ep4_t g) { + ep4_copy(g, core_get()->ep4_g); +} + +void ep4_curve_get_a(fp4_t a) { + fp4_copy(a, core_get()->ep4_a); +} + +void ep4_curve_get_b(fp4_t b) { + fp4_copy(b, core_get()->ep4_b); +} + +void ep4_curve_get_vs(bn_t *v) { + bn_t x, t; + + bn_null(x); + bn_null(t); + + RLC_TRY { + bn_new(x); + bn_new(t); + + fp_prime_get_par(x); + bn_copy(v[1], x); + bn_copy(v[2], x); + bn_copy(v[3], x); + + /* t = 2x^2. */ + bn_sqr(t, x); + bn_dbl(t, t); + + /* v0 = 2x^2 + 3x + 1. */ + bn_mul_dig(v[0], x, 3); + bn_add_dig(v[0], v[0], 1); + bn_add(v[0], v[0], t); + + /* v3 = -(2x^2 + x). */ + bn_add(v[3], v[3], t); + bn_neg(v[3], v[3]); + + /* v1 = 12x^3 + 8x^2 + x, v2 = 6x^3 + 4x^2 + x. */ + bn_dbl(t, t); + bn_add(v[2], v[2], t); + bn_dbl(t, t); + bn_add(v[1], v[1], t); + bn_rsh(t, t, 2); + bn_mul(t, t, x); + bn_mul_dig(t, t, 3); + bn_add(v[2], v[2], t); + bn_dbl(t, t); + bn_add(v[1], v[1], t); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(x); + bn_free(t); + } +} + +void ep4_curve_get_ord(bn_t n) { + ctx_t *ctx = core_get(); + if (ctx->ep4_is_twist) { + ep_curve_get_ord(n); + } else { + bn_copy(n, &(ctx->ep4_r)); + } +} + +void ep4_curve_get_cof(bn_t h) { + bn_copy(h, &(core_get()->ep4_h)); +} + +#if defined(EP_PRECO) + +ep4_t *ep4_curve_get_tab(void) { +#if ALLOC == AUTO + return (ep4_t *)*(core_get()->ep4_ptr); +#else + return core_get()->ep4_ptr; +#endif +} + +#endif + +void ep4_curve_set_twist(int type) { + char str[8 * RLC_FP_BYTES + 1]; + ctx_t *ctx = core_get(); + ep4_t g; + fp4_t a, b; + bn_t r, h; + + ep4_null(g); + fp4_null(a); + fp4_null(b); + bn_null(r); + bn_null(h); + + ctx->ep4_is_twist = 0; + if (type == RLC_EP_MTYPE || type == RLC_EP_DTYPE) { + ctx->ep4_is_twist = type; + } else { + return; + } + + RLC_TRY { + ep4_new(g); + fp4_new(a); + fp4_new(b); + bn_new(r); + bn_new(h); + + switch (ep_param_get()) { +#if FP_PRIME == 509 + case B24_P509: + ASSIGN(B24_P509); + break; +#endif + default: + (void)str; + RLC_THROW(ERR_NO_VALID); + break; + } + + fp4_zero(g->z); + fp4_set_dig(g->z, 1); + g->coord = BASIC; + + ep4_copy(ctx->ep4_g, g); + fp4_copy(ctx->ep4_a, a); + fp4_copy(ctx->ep4_b, b); + + detect_opt(&(ctx->ep4_opt_a), ctx->ep4_a); + detect_opt(&(ctx->ep4_opt_b), ctx->ep4_b); + + bn_copy(&(ctx->ep4_r), r); + bn_copy(&(ctx->ep4_h), h); + +#if defined(WITH_PC) + /* Compute pairing generator. */ + pc_core_calc(); +#endif + +#if defined(EP_PRECO) + ep4_mul_pre((ep4_t *)ep4_curve_get_tab(), ctx->ep4_g); +#endif + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(g); + fp4_free(a); + fp4_free(b); + bn_free(r); + bn_free(h); + } +} + +void ep4_curve_set(fp4_t a, fp4_t b, ep4_t g, bn_t r, bn_t h) { + ctx_t *ctx = core_get(); + ctx->ep4_is_twist = 0; + + fp4_copy(ctx->ep4_a, a); + fp4_copy(ctx->ep4_b, b); + + ep4_norm(ctx->ep4_g, g); + bn_copy(&(ctx->ep4_r), r); + bn_copy(&(ctx->ep4_h), h); + +#if defined(EP_PRECO) + ep4_mul_pre((ep4_t *)ep4_curve_get_tab(), ctx->ep4_g); +#endif +} diff --git a/contrib/relic/src/epx/relic_ep4_dbl.c b/contrib/relic/src/epx/relic_ep4_dbl.c new file mode 100644 index 000000000..11d0bb047 --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_dbl.c @@ -0,0 +1,276 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of doubling on elliptic prime curves over quartic + * extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +#if EP_ADD == BASIC || !defined(STRIP) + +/** + * Doubles a point represented in affine coordinates on an ordinary prime + * elliptic curve. + * + * @param[out] r - the result. + * @param[out] s - the resulting slope. + * @param[in] p - the point to double. + */ +static void ep4_dbl_basic_imp(ep4_t r, fp4_t s, ep4_t p) { + fp4_t t0, t1, t2; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + + /* t0 = 1/(2 * y1). */ + fp4_dbl(t0, p->y); + fp4_inv(t0, t0); + + /* t1 = 3 * x1^2 + a. */ + fp4_sqr(t1, p->x); + fp4_copy(t2, t1); + fp4_dbl(t1, t1); + fp4_add(t1, t1, t2); + + ep4_curve_get_a(t2); + fp4_add(t1, t1, t2); + + /* t1 = (3 * x1^2 + a)/(2 * y1). */ + fp4_mul(t1, t1, t0); + + if (s != NULL) { + fp4_copy(s, t1); + } + + /* t2 = t1^2. */ + fp4_sqr(t2, t1); + + /* x3 = t1^2 - 2 * x1. */ + fp4_dbl(t0, p->x); + fp4_sub(t0, t2, t0); + + /* y3 = t1 * (x1 - x3) - y1. */ + fp4_sub(t2, p->x, t0); + fp4_mul(t1, t1, t2); + + fp4_sub(r->y, t1, p->y); + + fp4_copy(r->x, t0); + fp4_copy(r->z, p->z); + + r->coord = BASIC; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + } +} + +#endif /* EP_ADD == BASIC */ + +#if EP_ADD == PROJC || !defined(STRIP) + +/** + * Doubles a point represented in affine coordinates on an ordinary prime + * elliptic curve. + * + * @param[out] r - the result. + * @param[in] p - the point to double. + */ +static void ep4_dbl_projc_imp(ep4_t r, ep4_t p) { + fp4_t t0, t1, t2, t3, t4, t5; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + fp4_null(t5); + + RLC_TRY { + if (ep_curve_opt_a() == RLC_ZERO) { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + fp4_new(t5); + + fp4_sqr(t0, p->x); + fp4_add(t2, t0, t0); + fp4_add(t0, t2, t0); + + fp4_sqr(t3, p->y); + fp4_mul(t1, t3, p->x); + fp4_add(t1, t1, t1); + fp4_add(t1, t1, t1); + fp4_sqr(r->x, t0); + fp4_add(t2, t1, t1); + fp4_sub(r->x, r->x, t2); + fp4_mul(r->z, p->z, p->y); + fp4_add(r->z, r->z, r->z); + fp4_add(t3, t3, t3); + + fp4_sqr(t3, t3); + fp4_add(t3, t3, t3); + fp4_sub(t1, t1, r->x); + fp4_mul(r->y, t0, t1); + fp4_sub(r->y, r->y, t3); + } else { + /* dbl-2007-bl formulas: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ + /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl */ + + /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ + fp4_sqr(t0, p->x); + fp4_sqr(t1, p->y); + fp4_sqr(t2, t1); + + if (p->coord != BASIC) { + /* t3 = z1^2. */ + fp4_sqr(t3, p->z); + + if (ep_curve_get_a() == RLC_ZERO) { + /* z3 = 2 * y1 * z1. */ + fp4_mul(r->z, p->y, p->z); + fp4_dbl(r->z, r->z); + } else { + /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ + fp4_add(r->z, p->y, p->z); + fp4_sqr(r->z, r->z); + fp4_sub(r->z, r->z, t1); + fp4_sub(r->z, r->z, t3); + } + } else { + /* z3 = 2 * y1. */ + fp4_dbl(r->z, p->y); + } + + /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ + fp4_add(t4, p->x, t1); + fp4_sqr(t4, t4); + fp4_sub(t4, t4, t0); + fp4_sub(t4, t4, t2); + fp4_dbl(t4, t4); + + /* t5 = M = 3 * x1^2 + a * z1^4. */ + fp4_dbl(t5, t0); + fp4_add(t5, t5, t0); + if (p->coord != BASIC) { + fp4_sqr(t3, t3); + ep4_curve_get_a(t1); + fp4_mul(t1, t3, t1); + fp4_add(t5, t5, t1); + } else { + ep4_curve_get_a(t1); + fp4_add(t5, t5, t1); + } + + /* x3 = T = M^2 - 2 * S. */ + fp4_sqr(r->x, t5); + fp4_dbl(t1, t4); + fp4_sub(r->x, r->x, t1); + + /* y3 = M * (S - T) - 8 * y1^4. */ + fp4_dbl(t2, t2); + fp4_dbl(t2, t2); + fp4_dbl(t2, t2); + fp4_sub(t4, t4, r->x); + fp4_mul(t5, t5, t4); + fp4_sub(r->y, t5, t2); + } + + r->coord = PROJC; + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + fp4_free(t5); + } +} + +#endif /* EP_ADD == PROJC */ + +/*============================================================================*/ + /* Public definitions */ +/*============================================================================*/ + +#if EP_ADD == BASIC || !defined(STRIP) + +void ep4_dbl_basic(ep4_t r, ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + ep4_dbl_basic_imp(r, NULL, p); +} + +void ep4_dbl_slp_basic(ep4_t r, fp4_t s, ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + ep4_dbl_basic_imp(r, s, p); +} + +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + +void ep4_dbl_projc(ep4_t r, ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + ep4_dbl_projc_imp(r, p); +} + +#endif diff --git a/contrib/relic/src/epx/relic_ep4_frb.c b/contrib/relic/src/epx/relic_ep4_frb.c new file mode 100644 index 000000000..fa216d53e --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_frb.c @@ -0,0 +1,48 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of frobenius action on prime elliptic curves over + * quartic extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_frb(ep4_t r, ep4_t p, int i) { + ep4_copy(r, p); + for (; i > 0; i--) { + fp4_frb(r->x, r->x, 1); + fp4_frb(r->y, r->y, 1); + fp4_frb(r->z, r->z, 1); + fp4_mul_frb(r->x, r->x, 1, 2); + fp4_mul_frb(r->y, r->y, 1, 3); + } +} diff --git a/contrib/relic/src/epx/relic_ep4_map.c b/contrib/relic/src/epx/relic_ep4_map.c new file mode 100644 index 000000000..be73b8d1e --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_map.c @@ -0,0 +1,79 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2012 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of hashing to a prime elliptic curve over a quadratic + * extension. + * + * @ingroup epx + */ + +#include "relic_core.h" +#include "relic_md.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_map(ep4_t p, const uint8_t *msg, int len) { + bn_t x; + fp4_t t0; + uint8_t digest[RLC_MD_LEN]; + + bn_null(x); + fp4_null(t0); + + RLC_TRY { + bn_new(x); + fp4_new(t0); + + md_map(digest, msg, len); + bn_read_bin(x, digest, RLC_MIN(RLC_FP_BYTES, RLC_MD_LEN)); + + fp4_zero(p->x); + fp_prime_conv(p->x[0][0], x); + fp4_set_dig(p->z, 1); + + while (1) { + ep4_rhs(t0, p); + + if (fp4_srt(p->y, t0)) { + p->coord = BASIC; + break; + } + + fp_add_dig(p->x[0][0], p->x[0][0], 1); + } + + ep4_mul_cof(p, p); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(x); + fp4_free(t0); + } +} diff --git a/contrib/relic/src/epx/relic_ep4_mul.c b/contrib/relic/src/epx/relic_ep4_mul.c new file mode 100644 index 000000000..c02f41b90 --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_mul.c @@ -0,0 +1,449 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2012 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of point multiplication on prime elliptic curves over + * quadratic extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +#if EP_MUL == LWNAF || !defined(STRIP) + +#if defined(EP_ENDOM) + +static void ep4_mul_glv_imp(ep4_t r, ep4_t p, const bn_t k) { + int sign, i, j, l, _l[8]; + bn_t n, _k[8], u, v; + int8_t naf[8][RLC_FP_BITS + 1]; + ep4_t q[8]; + + bn_null(n); + bn_null(u); + bn_null(v); + + RLC_TRY { + bn_new(n); + bn_new(u); + bn_new(v); + for (i = 0; i < 8; i++) { + bn_null(_k[i]); + ep4_null(q[i]); + bn_new(_k[i]); + ep4_new(q[i]); + } + + bn_abs(v, k); + ep4_curve_get_ord(n); + if (bn_cmp_abs(v, n) == RLC_GT) { + bn_mod(v, v, n); + } + + fp_prime_get_par(u); + sign = bn_sign(u); + bn_abs(u, u); + + ep4_norm(q[0], p); + for (i = 0; i < 8; i++) { + bn_mod(_k[i], v, u); + bn_div(v, v, u); + if ((sign == RLC_NEG) && (i % 2 != 0)) { + bn_neg(_k[i], _k[i]); + } + if (bn_sign(k) == RLC_NEG) { + bn_neg(_k[i], _k[i]); + } + if (i > 0) { + ep4_frb(q[i], q[i - 1], 1); + } + } + + l = 0; + for (i = 0; i < 8; i++) { + if (bn_sign(_k[i]) == RLC_NEG) { + ep4_neg(q[i], q[i]); + } + _l[i] = RLC_FP_BITS + 1; + bn_rec_naf(naf[i], &_l[i], _k[i], 2); + l = RLC_MAX(l, _l[i]); + } + + ep4_set_infty(r); + for (j = l - 1; j >= 0; j--) { + ep4_dbl(r, r); + + for (i = 0; i < 8; i++) { + if (naf[i][j] > 0) { + ep4_add(r, r, q[i]); + } + if (naf[i][j] < 0) { + ep4_sub(r, r, q[i]); + } + } + } + + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + bn_free(v); + for (i = 0; i < 8; i++) { + bn_free(_k[i]); + ep4_free(q[i]); + } + + } +} + +#endif /* EP_ENDOM */ + +static void ep4_mul_naf_imp(ep4_t r, ep4_t p, const bn_t k) { + int l, i, n; + int8_t naf[RLC_FP_BITS + 1]; + ep4_t t[1 << (EP_WIDTH - 2)]; + + RLC_TRY { + /* Prepare the precomputation table. */ + for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { + ep4_null(t[i]); + ep4_new(t[i]); + } + /* Compute the precomputation table. */ + ep4_tab(t, p, EP_WIDTH); + + /* Compute the w-NAF representation of k. */ + l = sizeof(naf); + bn_rec_naf(naf, &l, k, EP_WIDTH); + + ep4_set_infty(r); + for (i = l - 1; i >= 0; i--) { + ep4_dbl(r, r); + + n = naf[i]; + if (n > 0) { + ep4_add(r, r, t[n / 2]); + } + if (n < 0) { + ep4_sub(r, r, t[-n / 2]); + } + } + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + /* Free the precomputation table. */ + for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { + ep4_free(t[i]); + } + } +} + +#endif /* EP_MUL == LWNAF */ + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_mul_basic(ep4_t r, ep4_t p, const bn_t k) { + int i, l; + ep4_t t; + + ep4_null(t); + + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + RLC_TRY { + ep4_new(t); + l = bn_bits(k); + + if (bn_get_bit(k, l - 1)) { + ep4_copy(t, p); + } else { + ep4_set_infty(t); + } + + for (i = l - 2; i >= 0; i--) { + ep4_dbl(t, t); + if (bn_get_bit(k, i)) { + ep4_add(t, t, p); + } + } + + ep4_copy(r, t); + ep4_norm(r, r); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(t); + } +} + +#if EP_MUL == SLIDE || !defined(STRIP) + +void ep4_mul_slide(ep4_t r, ep4_t p, const bn_t k) { + ep4_t t[1 << (EP_WIDTH - 1)], q; + int i, j, l; + uint8_t win[RLC_FP_BITS + 1]; + + ep4_null(q); + + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + RLC_TRY { + for (i = 0; i < (1 << (EP_WIDTH - 1)); i ++) { + ep4_null(t[i]); + ep4_new(t[i]); + } + + ep4_new(q); + + ep4_copy(t[0], p); + ep4_dbl(q, p); + +#if defined(EP_MIXED) + ep4_norm(q, q); +#endif + + /* Create table. */ + for (i = 1; i < (1 << (EP_WIDTH - 1)); i++) { + ep4_add(t[i], t[i - 1], q); + } + +#if defined(EP_MIXED) + ep4_norm_sim(t + 1, t + 1, (1 << (EP_WIDTH - 1)) - 1); +#endif + + ep4_set_infty(q); + l = RLC_FP_BITS + 1; + bn_rec_slw(win, &l, k, EP_WIDTH); + for (i = 0; i < l; i++) { + if (win[i] == 0) { + ep4_dbl(q, q); + } else { + for (j = 0; j < util_bits_dig(win[i]); j++) { + ep4_dbl(q, q); + } + ep4_add(q, q, t[win[i] >> 1]); + } + } + + ep4_norm(r, q); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < (1 << (EP_WIDTH - 1)); i++) { + ep4_free(t[i]); + } + ep4_free(q); + } +} + +#endif + +#if EP_MUL == MONTY || !defined(STRIP) + +void ep4_mul_monty(ep4_t r, ep4_t p, const bn_t k) { + ep4_t t[2]; + + ep4_null(t[0]); + ep4_null(t[1]); + + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + RLC_TRY { + ep4_new(t[0]); + ep4_new(t[1]); + + ep4_set_infty(t[0]); + ep4_copy(t[1], p); + + for (int i = bn_bits(k) - 1; i >= 0; i--) { + int j = bn_get_bit(k, i); + dv_swap_cond(t[0]->x[0][0], t[1]->x[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->x[0][1], t[1]->x[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->x[1][0], t[1]->x[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->x[1][1], t[1]->x[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[0][0], t[1]->y[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[0][1], t[1]->y[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[1][0], t[1]->y[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[1][1], t[1]->y[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[0][0], t[1]->z[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[0][1], t[1]->z[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[1][0], t[1]->z[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[1][1], t[1]->z[1][1], RLC_FP_DIGS, j ^ 1); + ep4_add(t[0], t[0], t[1]); + ep4_dbl(t[1], t[1]); + dv_swap_cond(t[0]->x[0][0], t[1]->x[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->x[0][1], t[1]->x[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->x[1][0], t[1]->x[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->x[1][1], t[1]->x[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[0][0], t[1]->y[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[0][1], t[1]->y[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[1][0], t[1]->y[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->y[1][1], t[1]->y[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[0][0], t[1]->z[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[0][1], t[1]->z[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[1][0], t[1]->z[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_cond(t[0]->z[1][1], t[1]->z[1][1], RLC_FP_DIGS, j ^ 1); + } + + ep4_norm(r, t[0]); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(t[1]); + ep4_free(t[0]); + } +} + +#endif + +#if EP_MUL == LWNAF || !defined(STRIP) + +void ep4_mul_lwnaf(ep4_t r, ep4_t p, const bn_t k) { + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + +#if defined(EP_ENDOM) + if (ep_curve_is_endom()) { + if (ep_curve_opt_a() == RLC_ZERO) { + ep4_mul_glv_imp(r, p, k); + } else { + ep4_mul_naf_imp(r, p, k); + } + return; + } +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) + ep4_mul_naf_imp(r, p, k); +#endif +} + +#endif + +void ep4_mul_gen(ep4_t r, bn_t k) { + if (bn_is_zero(k)) { + ep4_set_infty(r); + return; + } + +#ifdef EP_PRECO + ep4_mul_fix(r, ep4_curve_get_tab(), k); +#else + ep4_t g; + + ep4_null(g); + + RLC_TRY { + ep4_new(g); + ep4_curve_get_gen(g); + ep4_mul(r, g, k); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(g); + } +#endif +} + +void ep4_mul_dig(ep4_t r, ep4_t p, dig_t k) { + int i, l; + ep4_t t; + + ep4_null(t); + + if (k == 0 || ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + RLC_TRY { + ep4_new(t); + + l = util_bits_dig(k); + + ep4_copy(t, p); + + for (i = l - 2; i >= 0; i--) { + ep4_dbl(t, t); + if (k & ((dig_t)1 << i)) { + ep4_add(t, t, p); + } + } + + ep4_norm(r, t); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(t); + } +} diff --git a/contrib/relic/src/epx/relic_ep4_mul_cof.c b/contrib/relic/src/epx/relic_ep4_mul_cof.c new file mode 100644 index 000000000..14f9973f2 --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_mul_cof.c @@ -0,0 +1,93 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of point multiplication of a prime elliptic curve over a + * quadratic extension by the curve cofactor. + * + * @ingroup epx + */ + +#include "relic_core.h" +#include "relic_md.h" +#include "relic_tmpl_map.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_mul_cof(ep4_t r, ep4_t p) { + bn_t z; + ep4_t t0, t1, t2, t3; + + ep4_null(t0); + ep4_null(t1); + ep4_null(t2); + ep4_null(t3); + bn_null(z); + + RLC_TRY { + ep4_new(t0); + ep4_new(t1); + ep4_new(t2); + ep4_new(t3); + + fp_prime_get_par(z); + + ep4_mul_basic(t0, p, z); + ep4_mul_basic(t1, t0, z); + ep4_mul_basic(t2, t1, z); + ep4_mul_basic(t3, t2, z); + + ep4_sub(t3, t3, t2); + ep4_sub(t3, t3, p); + ep4_sub(t2, t2, t1); + ep4_frb(t2, t2, 1); + + ep4_sub(t1, t1, t0); + ep4_frb(t1, t1, 2); + + ep4_sub(t0, t0, p); + ep4_frb(t0, t0, 3); + + ep4_dbl(r, p); + ep4_frb(r, r, 4); + ep4_add(r, r, t0); + ep4_add(r, r, t1); + ep4_add(r, r, t2); + ep4_add(r, r, t3); + + ep4_norm(r, r); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + ep4_free(t0); + ep4_free(t1); + ep4_free(t2); + ep4_free(t3); + bn_free(z); + + } +} diff --git a/contrib/relic/src/epx/relic_ep4_mul_fix.c b/contrib/relic/src/epx/relic_ep4_mul_fix.c new file mode 100644 index 000000000..8709e702b --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_mul_fix.c @@ -0,0 +1,393 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2012 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of fixed point multiplication on a prime elliptic curve over + * a quartic extension. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +#if EP_FIX == LWNAF || !defined(STRIP) + +/** + * Precomputes a table for a point multiplication on an ordinary curve. + * + * @param[out] t - the destination table. + * @param[in] p - the point to multiply. + */ +static void ep4_mul_pre_ordin(ep4_t *t, ep4_t p) { + int i; + + ep4_dbl(t[0], p); +#if defined(EP_MIXED) + ep4_norm(t[0], t[0]); +#endif + +#if EP_DEPTH > 2 + ep4_add(t[1], t[0], p); + for (i = 2; i < (1 << (EP_DEPTH - 2)); i++) { + ep4_add(t[i], t[i - 1], t[0]); + } + +#if defined(EP_MIXED) + for (i = 1; i < (1 << (EP_DEPTH - 2)); i++) { + ep4_norm(t[i], t[i]); + } +#endif + +#endif + ep4_copy(t[0], p); +} + +/** + * Multiplies a binary elliptic curve point by an integer using the w-NAF + * method. + * + * @param[out] r - the result. + * @param[in] p - the point to multiply. + * @param[in] k - the integer. + */ +static void ep4_mul_fix_ordin(ep4_t r, ep4_t *table, bn_t k) { + int len, i, n; + int8_t naf[2 * RLC_FP_BITS + 1], *t; + + if (bn_is_zero(k)) { + ep4_set_infty(r); + return; + } + + /* Compute the w-TNAF representation of k. */ + len = 2 * RLC_FP_BITS + 1; + bn_rec_naf(naf, &len, k, EP_DEPTH); + + t = naf + len - 1; + ep4_set_infty(r); + for (i = len - 1; i >= 0; i--, t--) { + ep4_dbl(r, r); + + n = *t; + if (n > 0) { + ep4_add(r, r, table[n / 2]); + } + if (n < 0) { + ep4_sub(r, r, table[-n / 2]); + } + } + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } +} + +#endif /* EP_FIX == LWNAF */ + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +#if EP_FIX == BASIC || !defined(STRIP) + +void ep4_mul_pre_basic(ep4_t *t, ep4_t p) { + bn_t n; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + ep4_curve_get_ord(n); + + ep4_copy(t[0], p); + for (int i = 1; i < bn_bits(n); i++) { + ep4_dbl(t[i], t[i - 1]); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + } +} + +void ep4_mul_fix_basic(ep4_t r, ep4_t *t, bn_t k) { + if (bn_is_zero(k)) { + ep4_set_infty(r); + return; + } + + ep4_set_infty(r); + + for (int i = 0; i < bn_bits(k); i++) { + if (bn_get_bit(k, i)) { + ep4_add(r, r, t[i]); + } + } + ep4_norm(r, r); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } +} + +#endif + +#if EP_FIX == COMBS || !defined(STRIP) + +void ep4_mul_pre_combs(ep4_t *t, ep4_t p) { + int i, j, l; + bn_t n; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + ep4_curve_get_ord(n); + l = bn_bits(n); + l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); + + ep4_set_infty(t[0]); + + ep4_copy(t[1], p); + for (j = 1; j < EP_DEPTH; j++) { + ep4_dbl(t[1 << j], t[1 << (j - 1)]); + for (i = 1; i < l; i++) { + ep4_dbl(t[1 << j], t[1 << j]); + } +#if defined(EP_MIXED) + ep4_norm(t[1 << j], t[1 << j]); +#endif + for (i = 1; i < (1 << j); i++) { + ep4_add(t[(1 << j) + i], t[i], t[1 << j]); + } + } +#if defined(EP_MIXED) + for (i = 1; i < RLC_EP_TABLE_COMBS; i++) { + ep4_norm(t[i], t[i]); + } +#endif + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + } +} + +void ep4_mul_fix_combs(ep4_t r, ep4_t *t, bn_t k) { + int i, j, l, w, n0, p0, p1; + bn_t n; + + if (bn_is_zero(k)) { + ep4_set_infty(r); + return; + } + + bn_null(n); + + RLC_TRY { + bn_new(n); + + ep4_curve_get_ord(n); + l = bn_bits(n); + l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); + + n0 = bn_bits(k); + + p0 = (EP_DEPTH) * l - 1; + + w = 0; + p1 = p0--; + for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) { + w = w << 1; + if (p1 < n0 && bn_get_bit(k, p1)) { + w = w | 1; + } + } + ep4_copy(r, t[w]); + + for (i = l - 2; i >= 0; i--) { + ep4_dbl(r, r); + + w = 0; + p1 = p0--; + for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) { + w = w << 1; + if (p1 < n0 && bn_get_bit(k, p1)) { + w = w | 1; + } + } + if (w > 0) { + ep4_add(r, r, t[w]); + } + } + ep4_norm(r, r); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + } +} + +#endif + +#if EP_FIX == COMBD || !defined(STRIP) + +void ep4_mul_pre_combd(ep4_t *t, ep4_t p) { + int i, j, d, e; + bn_t n; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + ep4_curve_get_ord(n); + d = bn_bits(n); + d = ((d % EP_DEPTH) == 0 ? (d / EP_DEPTH) : (d / EP_DEPTH) + 1); + e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1); + + ep4_set_infty(t[0]); + ep4_copy(t[1], p); + for (j = 1; j < EP_DEPTH; j++) { + ep4_dbl(t[1 << j], t[1 << (j - 1)]); + for (i = 1; i < d; i++) { + ep4_dbl(t[1 << j], t[1 << j]); + } +#if defined(EP_MIXED) + ep4_norm(t[1 << j], t[1 << j]); +#endif + for (i = 1; i < (1 << j); i++) { + ep4_add(t[(1 << j) + i], t[i], t[1 << j]); + } + } + ep4_set_infty(t[1 << EP_DEPTH]); + for (j = 1; j < (1 << EP_DEPTH); j++) { + ep4_dbl(t[(1 << EP_DEPTH) + j], t[j]); + for (i = 1; i < e; i++) { + ep4_dbl(t[(1 << EP_DEPTH) + j], t[(1 << EP_DEPTH) + j]); + } + } +#if defined(EP_MIXED) + for (i = 1; i < RLC_EP_TABLE_COMBD; i++) { + ep4_norm(t[i], t[i]); + } +#endif + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + } +} + +void ep4_mul_fix_combd(ep4_t r, ep4_t *t, bn_t k) { + int i, j, d, e, w0, w1, n0, p0, p1; + bn_t n; + + if (bn_is_zero(k)) { + ep4_set_infty(r); + return; + } + + bn_null(n); + + RLC_TRY { + bn_new(n); + + ep4_curve_get_ord(n); + d = bn_bits(n); + d = ((d % EP_DEPTH) == 0 ? (d / EP_DEPTH) : (d / EP_DEPTH) + 1); + e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1); + + ep4_set_infty(r); + n0 = bn_bits(k); + + p1 = (e - 1) + (EP_DEPTH - 1) * d; + for (i = e - 1; i >= 0; i--) { + ep4_dbl(r, r); + + w0 = 0; + p0 = p1; + for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) { + w0 = w0 << 1; + if (p0 < n0 && bn_get_bit(k, p0)) { + w0 = w0 | 1; + } + } + + w1 = 0; + p0 = p1-- + e; + for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) { + w1 = w1 << 1; + if (i + e < d && p0 < n0 && bn_get_bit(k, p0)) { + w1 = w1 | 1; + } + } + + ep4_add(r, r, t[w0]); + ep4_add(r, r, t[(1 << EP_DEPTH) + w1]); + } + ep4_norm(r, r); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(r, r); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + } +} + +#endif + +#if EP_FIX == LWNAF || !defined(STRIP) + +void ep4_mul_pre_lwnaf(ep4_t *t, ep4_t p) { + ep4_mul_pre_ordin(t, p); +} + +void ep4_mul_fix_lwnaf(ep4_t r, ep4_t *t, bn_t k) { + ep4_mul_fix_ordin(r, t, k); +} + +#endif diff --git a/contrib/relic/src/epx/relic_ep4_mul_sim.c b/contrib/relic/src/epx/relic_ep4_mul_sim.c new file mode 100644 index 000000000..faff8f0c3 --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_mul_sim.c @@ -0,0 +1,628 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2012 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of simultaneous point multiplication on a prime elliptic + * curve over a quartic extension. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +#if EP_SIM == INTER || !defined(STRIP) + +/** + * Multiplies and adds two prime elliptic curve points simultaneously, + * optionally choosing the first point as the generator depending on an optional + * table of precomputed points. + * + * @param[out] r - the result. + * @param[in] p - the first point to multiply. + * @param[in] k - the first integer. + * @param[in] q - the second point to multiply. + * @param[in] m - the second integer. + * @param[in] t - the pointer to the precomputed table. + */ +static void ep4_mul_sim_plain(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m, + ep4_t *t) { + int i, l, l0, l1, n0, n1, w, gen; + int8_t naf0[2 * RLC_FP_BITS + 1], naf1[2 * RLC_FP_BITS + 1], *_k, *_m; + ep4_t t0[1 << (EP_WIDTH - 2)]; + ep4_t t1[1 << (EP_WIDTH - 2)]; + + RLC_TRY { + gen = (t == NULL ? 0 : 1); + if (!gen) { + for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { + ep4_null(t0[i]); + ep4_new(t0[i]); + } + ep4_tab(t0, p, EP_WIDTH); + t = (ep4_t *)t0; + } + + /* Prepare the precomputation table. */ + for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { + ep4_null(t1[i]); + ep4_new(t1[i]); + } + /* Compute the precomputation table. */ + ep4_tab(t1, q, EP_WIDTH); + + /* Compute the w-TNAF representation of k. */ + if (gen) { + w = EP_DEPTH; + } else { + w = EP_WIDTH; + } + l0 = l1 = 2 * RLC_FP_BITS + 1; + bn_rec_naf(naf0, &l0, k, w); + bn_rec_naf(naf1, &l1, m, EP_WIDTH); + + l = RLC_MAX(l0, l1); + _k = naf0 + l - 1; + _m = naf1 + l - 1; + if (bn_sign(k) == RLC_NEG) { + for (i = 0; i < l0; i++) { + naf0[i] = -naf0[i]; + } + } + if (bn_sign(m) == RLC_NEG) { + for (i = 0; i < l1; i++) { + naf1[i] = -naf1[i]; + } + } + + ep4_set_infty(r); + for (i = l - 1; i >= 0; i--, _k--, _m--) { + ep4_dbl(r, r); + + n0 = *_k; + n1 = *_m; + if (n0 > 0) { + ep4_add(r, r, t[n0 / 2]); + } + if (n0 < 0) { + ep4_sub(r, r, t[-n0 / 2]); + } + if (n1 > 0) { + ep4_add(r, r, t1[n1 / 2]); + } + if (n1 < 0) { + ep4_sub(r, r, t1[-n1 / 2]); + } + } + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + /* Free the precomputation tables. */ + if (!gen) { + for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { + ep4_free(t0[i]); + } + } + for (i = 0; i < (1 << (EP_WIDTH - 2)); i++) { + ep4_free(t1[i]); + } + } +} + +#endif /* EP_SIM == INTER */ + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +#if EP_SIM == BASIC || !defined(STRIP) + +void ep4_mul_sim_basic(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t l) { + ep4_t t; + + ep4_null(t); + + RLC_TRY { + ep4_new(t); + ep4_mul(t, q, l); + ep4_mul(r, p, k); + ep4_add(t, t, r); + ep4_norm(r, t); + + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(t); + } +} + +#endif + +#if EP_SIM == TRICK || !defined(STRIP) + +void ep4_mul_sim_trick(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m) { + ep4_t t0[1 << (EP_WIDTH / 2)]; + ep4_t t1[1 << (EP_WIDTH / 2)]; + ep4_t t[1 << EP_WIDTH]; + bn_t n; + int l0, l1, w = EP_WIDTH / 2; + uint8_t w0[2 * RLC_FP_BITS], w1[2 * RLC_FP_BITS]; + + bn_null(n); + + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_mul(r, q, m); + return; + } + if (bn_is_zero(m) || ep4_is_infty(q)) { + ep4_mul(r, p, k); + return; + } + + RLC_TRY { + bn_new(n); + + ep4_curve_get_ord(n); + + for (int i = 0; i < (1 << w); i++) { + ep4_null(t0[i]); + ep4_null(t1[i]); + ep4_new(t0[i]); + ep4_new(t1[i]); + } + for (int i = 0; i < (1 << EP_WIDTH); i++) { + ep4_null(t[i]); + ep4_new(t[i]); + } + + ep4_set_infty(t0[0]); + ep4_copy(t0[1], p); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(t0[1], t0[1]); + } + for (int i = 2; i < (1 << w); i++) { + ep4_add(t0[i], t0[i - 1], t0[1]); + } + + ep4_set_infty(t1[0]); + ep4_copy(t1[1], q); + if (bn_sign(m) == RLC_NEG) { + ep4_neg(t1[1], t1[1]); + } + for (int i = 1; i < (1 << w); i++) { + ep4_add(t1[i], t1[i - 1], t1[1]); + } + + for (int i = 0; i < (1 << w); i++) { + for (int j = 0; j < (1 << w); j++) { + ep4_add(t[(i << w) + j], t0[i], t1[j]); + } + } + +#if defined(EP_MIXED) + ep4_norm_sim(t + 1, t + 1, (1 << (EP_WIDTH)) - 1); +#endif + + l0 = l1 = RLC_CEIL(2 * RLC_FP_BITS, w); + bn_rec_win(w0, &l0, k, w); + bn_rec_win(w1, &l1, m, w); + + for (int i = l0; i < l1; i++) { + w0[i] = 0; + } + for (int i = l1; i < l0; i++) { + w1[i] = 0; + } + + ep4_set_infty(r); + for (int i = RLC_MAX(l0, l1) - 1; i >= 0; i--) { + for (int j = 0; j < w; j++) { + ep4_dbl(r, r); + } + ep4_add(r, r, t[(w0[i] << w) + w1[i]]); + } + ep4_norm(r, r); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + for (int i = 0; i < (1 << w); i++) { + ep4_free(t0[i]); + ep4_free(t1[i]); + } + for (int i = 0; i < (1 << EP_WIDTH); i++) { + ep4_free(t[i]); + } + } +} +#endif + +#if EP_SIM == INTER || !defined(STRIP) + +void ep4_mul_sim_inter(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m) { + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_mul(r, q, m); + return; + } + if (bn_is_zero(m) || ep4_is_infty(q)) { + ep4_mul(r, p, k); + return; + } + + ep4_mul_sim_plain(r, p, k, q, m, NULL); +} + +#endif + +#if EP_SIM == JOINT || !defined(STRIP) + +void ep4_mul_sim_joint(ep4_t r, ep4_t p, bn_t k, ep4_t q, bn_t m) { + ep4_t t[5]; + int i, l, u_i, offset; + int8_t jsf[4 * (RLC_FP_BITS + 1)]; + + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_mul(r, q, m); + return; + } + if (bn_is_zero(m) || ep4_is_infty(q)) { + ep4_mul(r, p, k); + return; + } + + RLC_TRY { + for (i = 0; i < 5; i++) { + ep4_null(t[i]); + ep4_new(t[i]); + } + + ep4_set_infty(t[0]); + ep4_copy(t[1], q); + if (bn_sign(m) == RLC_NEG) { + ep4_neg(t[1], t[1]); + } + ep4_copy(t[2], p); + if (bn_sign(k) == RLC_NEG) { + ep4_neg(t[2], t[2]); + } + ep4_add(t[3], t[2], t[1]); + ep4_sub(t[4], t[2], t[1]); +#if defined(EP_MIXED) + ep4_norm_sim(t + 3, t + 3, 2); +#endif + + l = 4 * (RLC_FP_BITS + 1); + bn_rec_jsf(jsf, &l, k, m); + + ep4_set_infty(r); + + offset = RLC_MAX(bn_bits(k), bn_bits(m)) + 1; + for (i = l - 1; i >= 0; i--) { + ep4_dbl(r, r); + if (jsf[i] != 0 && jsf[i] == -jsf[i + offset]) { + u_i = jsf[i] * 2 + jsf[i + offset]; + if (u_i < 0) { + ep4_sub(r, r, t[4]); + } else { + ep4_add(r, r, t[4]); + } + } else { + u_i = jsf[i] * 2 + jsf[i + offset]; + if (u_i < 0) { + ep4_sub(r, r, t[-u_i]); + } else { + ep4_add(r, r, t[u_i]); + } + } + } + ep4_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < 5; i++) { + ep4_free(t[i]); + } + } +} + +#endif + +void ep4_mul_sim_gen(ep4_t r, bn_t k, ep4_t q, bn_t m) { + ep4_t gen; + + ep4_null(gen); + + if (bn_is_zero(k)) { + ep4_mul(r, q, m); + return; + } + if (bn_is_zero(m) || ep4_is_infty(q)) { + ep4_mul_gen(r, k); + return; + } + + RLC_TRY { + ep4_new(gen); + + ep4_curve_get_gen(gen); +#if EP_FIX == LWNAF && defined(EP_PRECO) + ep4_mul_sim_plain(r, gen, k, q, m, ep4_curve_get_tab()); +#else + ep4_mul_sim(r, gen, k, q, m); +#endif + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(gen); + } +} + +void ep4_mul_sim_dig(ep4_t r, ep4_t p[], dig_t k[], int len) { + ep4_t t; + int max; + + ep4_null(t); + + max = util_bits_dig(k[0]); + for (int i = 1; i < len; i++) { + max = RLC_MAX(max, util_bits_dig(k[i])); + } + + RLC_TRY { + ep4_new(t); + + ep4_set_infty(t); + for (int i = max - 1; i >= 0; i--) { + ep4_dbl(t, t); + for (int j = 0; j < len; j++) { + if (k[j] & ((dig_t)1 << i)) { + ep4_add(t, t, p[j]); + } + } + } + + ep4_norm(r, t); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(t); + } +} + +void ep4_mul_sim_lot(ep4_t r, ep4_t p[], const bn_t k[], int n) { + const int len = RLC_FP_BITS + 1; + int i, j, m, l, *_l = RLC_ALLOCA(int, 8 * n); + bn_t _k[8], q, x; + int8_t *naf = RLC_ALLOCA(int8_t, 8 * n * len); + + bn_null(q); + bn_null(x); + + if (n <= 10) { + ep4_t *_p = RLC_ALLOCA(ep4_t, 8 * n); + + RLC_TRY { + bn_new(q); + bn_new(x); + for (j = 0; j < 8; j++) { + bn_null(_k[j]); + bn_new(_k[j]); + for (i = 0; i < n; i++) { + ep4_null(_p[8*i + j]); + ep4_new(_p[8*i + j]); + } + } + + for (int i = 0; i < n; i++) { + ep4_norm(_p[8*i], p[i]); + ep4_frb(_p[8*i + 1], _p[8*i], 1); + ep4_frb(_p[8*i + 2], _p[8*i + 1], 1); + ep4_frb(_p[8*i + 3], _p[8*i + 2], 1); + ep4_frb(_p[8*i + 4], _p[8*i + 3], 1); + ep4_frb(_p[8*i + 5], _p[8*i + 4], 1); + ep4_frb(_p[8*i + 6], _p[8*i + 5], 1); + ep4_frb(_p[8*i + 7], _p[8*i + 6], 1); + } + + ep_curve_get_ord(q); + fp_prime_get_par(x); + + l = 0; + for (i = 0; i < n; i++) { + bn_rec_frb(_k, 8, k[i], q, x, ep_curve_is_pairf()); + for (j = 0; j < 8; j++) { + _l[8*i + j] = len; + bn_rec_naf(&naf[(8*i + j)*len], &_l[8*i + j], _k[j], 2); + if (bn_sign(_k[j]) == RLC_NEG) { + ep4_neg(_p[8*i + j], _p[8*i + j]); + } + l = RLC_MAX(l, _l[8*i + j]); + } + } + + for (i = 0; i < n; i++) { + for (j = 0; j < 8; j++) { + for (m = _l[8*i + j]; m < l; m++) { + naf[(8*i + j)*len + m] = 0; + } + } + } + + ep4_set_infty(r); + for (i = l - 1; i >= 0; i--) { + ep4_dbl(r, r); + for (j = 0; j < n; j++) { + for (m = 0; m < 8; m++) { + if (naf[(8*j + m)*len + i] > 0) { + ep4_add(r, r, _p[8*j + m]); + } + if (naf[(8*j + m)*len + i] < 0) { + ep4_sub(r, r, _p[8*j + m]); + } + } + } + } + + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(q); + bn_free(x); + for (j = 0; j < 8; j++) { + bn_free(_k[j]); + for (i = 0; i < n; i++) { + ep4_free(_p[8*i + j]); + } + } + RLC_FREE(_l); + RLC_FREE(_p); + RLC_FREE(naf); + } + } else { + const int w = RLC_MAX(2, util_bits_dig(n) - 2), c = (1 << (w - 2)); + ep4_t s, t, u, v, *_p = RLC_ALLOCA(ep4_t, 8 * c); + int8_t ptr; + + ep4_null(s); + ep4_null(t); + ep4_null(u); + ep4_null(v); + + RLC_TRY { + bn_new(q); + bn_new(x); + ep4_new(s); + ep4_new(t); + ep4_new(u); + ep4_new(v); + for (i = 0; i < 8; i++) { + bn_null(_k[i]); + bn_new(_k[i]); + for (j = 0; j < c; j++) { + ep4_null(_p[i*c + j]); + ep4_new(_p[i*c + j]); + ep4_set_infty(_p[i*c + j]); + } + } + + ep_curve_get_ord(q); + fp_prime_get_par(x); + + l = 0; + for (i = 0; i < n; i++) { + bn_rec_frb(_k, 8, k[i], q, x, ep_curve_is_pairf()); + for (j = 0; j < 8; j++) { + _l[8*i + j] = len; + bn_rec_naf(&naf[(8*i + j)*len], &_l[8*i + j], _k[j], w); + l = RLC_MAX(l, _l[8*i + j]); + } + } + + for (i = 0; i < n; i++) { + for (j = 0; j < 8; j++) { + for (m = _l[8*i + j]; m < l; m++) { + naf[(8*i + j)*len + m] = 0; + } + } + } + + ep4_set_infty(s); + for (i = l - 1; i >= 0; i--) { + for (j = 0; j < n; j++) { + for (m = 0; m < 8; m++) { + ptr = naf[(8*j + m)*len + i]; + if (ptr != 0) { + ep4_copy(t, p[j]); + if (ptr < 0) { + ptr = -ptr; + ep4_neg(t, t); + } + if (bn_sign(_k[m]) == RLC_NEG) { + ep4_neg(t, t); + } + ep4_add(_p[m*c + (ptr >> 1)], _p[m*c + (ptr >> 1)], t); + } + } + } + + ep4_set_infty(t); + for (m = 3; m >= 0; m--) { + ep4_frb(t, t, 1); + ep4_set_infty(u); + ep4_set_infty(v); + for (j = c - 1; j >= 0; j--) { + ep4_add(u, u, _p[m*c + j]); + if (j == 0) { + ep4_dbl(v, v); + } + ep4_add(v, v, u); + ep4_set_infty(_p[m*c + j]); + } + ep4_add(t, t, v); + } + ep4_dbl(s, s); + ep4_add(s, s, t); + } + + /* Convert r to affine coordinates. */ + ep4_norm(r, s); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(q); + bn_free(x); + ep4_free(s); + ep4_free(t); + ep4_free(u); + ep4_free(v); + for (i = 0; i < 8; i++) { + bn_free(_k[i]); + for (j = 0; j < c; j++) { + ep4_free(_p[i*c + j]); + } + } + RLC_FREE(_l); + RLC_FREE(_p); + RLC_FREE(naf); + } + } +} diff --git a/contrib/relic/src/epx/relic_ep4_neg.c b/contrib/relic/src/epx/relic_ep4_neg.c new file mode 100644 index 000000000..4351c809c --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_neg.c @@ -0,0 +1,53 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of point negation on elliptic prime curves over quartic + * extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_neg(ep4_t r, ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + if (r != p) { + fp4_copy(r->x, p->x); + fp4_copy(r->z, p->z); + } + + fp4_neg(r->y, p->y); + + r->coord = p->coord; +} diff --git a/contrib/relic/src/epx/relic_ep4_norm.c b/contrib/relic/src/epx/relic_ep4_norm.c new file mode 100644 index 000000000..8ad02259c --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_norm.c @@ -0,0 +1,138 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of point normalization on prime elliptic curves over quartic + * extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +#if EP_ADD == PROJC || !defined(STRIP) + +/** + * Normalizes a point represented in projective coordinates. + * + * @param r - the result. + * @param p - the point to normalize. + */ +static void ep4_norm_imp(ep4_t r, ep4_t p, int inverted) { + if (p->coord != BASIC) { + fp4_t t0, t1; + + fp4_null(t0); + fp4_null(t1); + + RLC_TRY { + + fp4_new(t0); + fp4_new(t1); + + if (inverted) { + fp4_copy(t1, p->z); + } else { + fp4_inv(t1, p->z); + } + fp4_sqr(t0, t1); + fp4_mul(r->x, p->x, t0); + fp4_mul(t0, t0, t1); + fp4_mul(r->y, p->y, t0); + fp4_set_dig(r->z, 1); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + } + } + + r->coord = BASIC; +} + +#endif /* EP_ADD == PROJC */ + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void ep4_norm(ep4_t r, ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + if (p->coord == BASIC) { + /* If the point is represented in affine coordinates, we just copy it. */ + ep4_copy(r, p); + } +#if EP_ADD == PROJC || !defined(STRIP) + ep4_norm_imp(r, p, 0); +#endif +} + +void ep4_norm_sim(ep4_t *r, ep4_t *t, int n) { + int i; + fp4_t *a = RLC_ALLOCA(fp4_t, n); + + RLC_TRY { + if (a == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < n; i++) { + fp4_null(a[i]); + fp4_new(a[i]); + fp4_copy(a[i], t[i]->z); + } + + fp4_inv_sim(a, a, n); + + for (i = 0; i < n; i++) { + fp4_copy(r[i]->x, t[i]->x); + fp4_copy(r[i]->y, t[i]->y); + fp4_copy(r[i]->z, a[i]); + } + + for (i = 0; i < n; i++) { + ep4_norm_imp(r[i], r[i], 1); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < n; i++) { + fp4_free(a[i]); + } + RLC_FREE(a); + } +} diff --git a/contrib/relic/src/epx/relic_ep4_util.c b/contrib/relic/src/epx/relic_ep4_util.c new file mode 100644 index 000000000..1bba16f2b --- /dev/null +++ b/contrib/relic/src/epx/relic_ep4_util.c @@ -0,0 +1,318 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of comparison for points on prime elliptic curves over + * quartic extensions. + * + * @ingroup epx + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int ep4_is_infty(ep4_t p) { + return (fp4_is_zero(p->z) == 1); +} + +void ep4_set_infty(ep4_t p) { + fp4_zero(p->x); + fp4_zero(p->y); + fp4_zero(p->z); + p->coord = BASIC; +} + +void ep4_copy(ep4_t r, ep4_t p) { + fp4_copy(r->x, p->x); + fp4_copy(r->y, p->y); + fp4_copy(r->z, p->z); + r->coord = p->coord; +} + +void ep4_rand(ep4_t p) { + bn_t n, k; + + bn_null(k); + bn_null(n); + + RLC_TRY { + bn_new(k); + bn_new(n); + + ep4_curve_get_ord(n); + bn_rand_mod(k, n); + + ep4_mul_gen(p, k); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(k); + bn_free(n); + } +} + +void ep4_blind(ep4_t r, ep4_t p) { + fp4_t rand; + + fp4_null(rand); + + RLC_TRY { + fp4_new(rand); + fp4_rand(rand); +#if EP_ADD == BASIC + (void)rand; + ep4_copy(r, p); +#else + fp4_mul(r->z, p->z, rand); + fp4_mul(r->y, p->y, rand); + fp4_sqr(rand, rand); + fp4_mul(r->x, r->x, rand); + fp4_mul(r->y, r->y, rand); + r->coord = EP_ADD; +#endif + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp4_free(rand); + } +} + +void ep4_rhs(fp4_t rhs, ep4_t p) { + fp4_t t0, t1; + + fp4_null(t0); + fp4_null(t1); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + + fp4_sqr(t0, p->x); /* x1^2 */ + + switch (ep4_curve_opt_a()) { + case RLC_ZERO: + break; +#if FP_RDC != MONTY + case RLC_MIN3: + fp4_sub_dig(t0, t0, 3); + break; + case RLC_ONE: + fp4_add_dig(t0, t0, 1); + break; + case RLC_TWO: + fp4_add_dig(t0, t0, 2); + break; + case RLC_TINY: + ep4_curve_get_a(t1); + fp4_mul_dig(t0, t0, t1[0][0]); + break; +#endif + default: + ep4_curve_get_a(t1); + fp4_add(t0, t0, t1); + break; + } + + fp4_mul(t0, t0, p->x); /* x1^3 + a * x */ + + switch (ep4_curve_opt_b()) { + case RLC_ZERO: + break; +#if FP_RDC != MONTY + case RLC_MIN3: + fp4_sub_dig(t0, t0, 3); + break; + case RLC_ONE: + fp4_add_dig(t0, t0, 1); + break; + case RLC_TWO: + fp4_add_dig(t0, t0, 2); + break; + case RLC_TINY: + ep4_curve_get_b(t1); + fp4_mul_dig(t0, t0, t1[0][0]); + break; +#endif + default: + ep4_curve_get_b(t1); + fp4_add(t0, t0, t1); + break; + } + + fp4_copy(rhs, t0); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + } +} + + +int ep4_on_curve(ep4_t p) { + ep4_t t; + int r = 0; + + ep4_null(t); + + RLC_TRY { + ep4_new(t); + + ep4_norm(t, p); + + ep4_rhs(t->x, t); + fp4_sqr(t->y, t->y); + + r = (fp4_cmp(t->x, t->y) == RLC_EQ) || ep4_is_infty(p); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + ep4_free(t); + } + return r; +} + +void ep4_tab(ep4_t *t, ep4_t p, int w) { + if (w > 2) { + ep4_dbl(t[0], p); +#if defined(EP_MIXED) + ep4_norm(t[0], t[0]); +#endif + ep4_add(t[1], t[0], p); + for (int i = 2; i < (1 << (w - 2)); i++) { + ep4_add(t[i], t[i - 1], t[0]); + } +#if defined(EP_MIXED) + ep4_norm_sim(t + 1, t + 1, (1 << (w - 2)) - 1); +#endif + } + ep4_copy(t[0], p); +} + +void ep4_print(ep4_t p) { + fp4_print(p->x); + fp4_print(p->y); + fp4_print(p->z); +} + +int ep4_size_bin(ep4_t a, int pack) { + ep4_t t; + int size = 0; + + ep4_null(t); + + if (ep4_is_infty(a)) { + return 1; + } + + RLC_TRY { + ep4_new(t); + + ep4_norm(t, a); + + size = 1 + 8 * RLC_FP_BYTES; + //TODO: Implement compression. + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + ep4_free(t); + } + + return size; +} + +void ep4_read_bin(ep4_t a, const uint8_t *bin, int len) { + if (len == 1) { + if (bin[0] == 0) { + ep4_set_infty(a); + return; + } else { + RLC_THROW(ERR_NO_BUFFER); + return; + } + } + + if (len != (8 * RLC_FP_BYTES + 1)) { + RLC_THROW(ERR_NO_BUFFER); + return; + } + + a->coord = BASIC; + fp4_set_dig(a->z, 1); + fp4_read_bin(a->x, bin + 1, 4 * RLC_FP_BYTES); + + if (len == 8 * RLC_FP_BYTES + 1) { + if (bin[0] == 4) { + fp4_read_bin(a->y, bin + 4 * RLC_FP_BYTES + 1, 4 * RLC_FP_BYTES); + } else { + RLC_THROW(ERR_NO_VALID); + return; + } + } + + if (!ep4_on_curve(a)) { + RLC_THROW(ERR_NO_VALID); + } +} + +void ep4_write_bin(uint8_t *bin, int len, ep4_t a, int pack) { + ep4_t t; + + ep4_null(t); + + memset(bin, 0, len); + + if (ep4_is_infty(a)) { + if (len < 1) { + RLC_THROW(ERR_NO_BUFFER); + return; + } else { + return; + } + } + + RLC_TRY { + ep4_new(t); + + ep4_norm(t, a); + + if (len < 8 * RLC_FP_BYTES + 1) { + RLC_THROW(ERR_NO_BUFFER); + } else { + bin[0] = 4; + fp4_write_bin(bin + 1, 4 * RLC_FP_BYTES, t->x); + fp4_write_bin(bin + 4 * RLC_FP_BYTES + 1, 4 * RLC_FP_BYTES, t->y); + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + ep4_free(t); + } +} diff --git a/contrib/relic/src/fb/relic_fb_itr.c b/contrib/relic/src/fb/relic_fb_itr.c index 95e81eafb..7ad4dd761 100644 --- a/contrib/relic/src/fb/relic_fb_itr.c +++ b/contrib/relic/src/fb/relic_fb_itr.c @@ -56,7 +56,7 @@ void fb_itr_basic(fb_t c, const fb_t a, int b) { } } -void fb_itr_pre_quick(fb_t *t, int b) { +void fb_itr_pre_quick(fb_st *t, int b) { int i, j, k; fb_t r; @@ -80,11 +80,7 @@ void fb_itr_pre_quick(fb_t *t, int b) { } } -#if ALLOC == AUTO fb_copy((dig_t *)t + (4 * i + j) * RLC_FB_DIGS, r); -#else - fb_copy(t[4 * i + j], r); -#endif } } } RLC_CATCH_ANY { @@ -94,6 +90,6 @@ void fb_itr_pre_quick(fb_t *t, int b) { } } -void fb_itr_quick(fb_t c, const fb_t a, const fb_t *t) { +void fb_itr_quick(fb_t c, const fb_t a, const fb_st *t) { fb_itrn_low(c, a, (dig_t *)t); } diff --git a/contrib/relic/src/fb/relic_fb_poly.c b/contrib/relic/src/fb/relic_fb_poly.c index 7fd38a8e0..0e67cf073 100644 --- a/contrib/relic/src/fb/relic_fb_poly.c +++ b/contrib/relic/src/fb/relic_fb_poly.c @@ -267,12 +267,6 @@ static void find_chain(void) { break; } - for (i = 0; i < RLC_TERMS; i++) { - for (j = 0; j < RLC_FB_TABLE; j++) { - ctx->fb_tab_ptr[i][j] = &(ctx->fb_tab_sqr[i][j]); - } - } - u[0] = 1; u[1] = 2; for (i = 2; i <= ctx->chain_len; i++) { @@ -286,7 +280,7 @@ static void find_chain(void) { } for (i = 0; i <= ctx->chain_len; i++) { - fb_itr_pre((fb_t *)fb_poly_tab_sqr(i), u[i]); + fb_itr_pre((fb_st *)fb_poly_tab_sqr(i), u[i]); } } @@ -436,15 +430,10 @@ dig_t *fb_poly_get_srz(void) { #endif } -const fb_t *fb_poly_tab_sqr(int i) { +const fb_st *fb_poly_tab_sqr(int i) { #if FB_INV == ITOHT || !defined(STRIP) /* If ITOHT inversion is used and tables are precomputed, return them. */ -#if ALLOC == AUTO - return (const fb_t *)*core_get()->fb_tab_ptr[i]; -#else - return (const fb_t *)core_get()->fb_tab_ptr[i]; -#endif - + return (const fb_st *)core_get()->fb_tab_sqr[i]; #else return NULL; #endif diff --git a/contrib/relic/src/fp/relic_fp_inv.c b/contrib/relic/src/fp/relic_fp_inv.c index 1ff56e27c..1805ab4bd 100644 --- a/contrib/relic/src/fp/relic_fp_inv.c +++ b/contrib/relic/src/fp/relic_fp_inv.c @@ -399,31 +399,27 @@ void fp_inv_exgcd(fp_t c, const fp_t a) { #endif -#include "assert.h" - #if FP_INV == DIVST || !defined(STRIP) void fp_inv_divst(fp_t c, const fp_t a) { - /* Compute number of iteratios based on modulus size. */ + /* Compute number of iterations based on modulus size. */ #if FP_PRIME < 46 - int d = (49 * FP_PRIME + 80)/17; + int d = (49 * FP_PRIME + 80) / 17; #else - int d = (49 * FP_PRIME + 57)/17; + int d = (49 * FP_PRIME + 57) / 17; #endif int g0, d0; dig_t fs, gs, delta = 1; bn_t _t; - dv_t f, g, t, u; - fp_t precomp, v, r; + fp_t f, g, t, u, v, r; bn_null(_t); - dv_null(f); - dv_null(g); - dv_null(t); - dv_null(u); + fp_null(f); + fp_null(g); + fp_null(t); + fp_null(u); fp_null(v); fp_null(r); - fp_null(precomp); if (fp_is_zero(a)) { RLC_THROW(ERR_NO_VALID); @@ -432,19 +428,12 @@ void fp_inv_divst(fp_t c, const fp_t a) { RLC_TRY { bn_new(_t); - dv_new(f); - dv_new(g); - dv_new(t); - dv_new(u); + fp_new(f); + fp_new(g); + fp_new(t); + fp_new(u); fp_new(v); fp_new(r); - fp_new(precomp); - - bn_set_dig(_t, d); - dv_copy(precomp, fp_prime_get(), RLC_FP_DIGS); - fp_add_dig(precomp, precomp, 1); - fp_hlv(precomp, precomp); - fp_exp(precomp, precomp, _t); fp_zero(v); fp_set_dig(r, 1); @@ -491,18 +480,317 @@ void fp_inv_divst(fp_t c, const fp_t a) { } fp_neg(t, v); dv_copy_cond(v, t, RLC_FP_DIGS, fs); - fp_mul(c, v, precomp); + + dv_copy(t, fp_prime_get(), RLC_FP_DIGS); + fp_add_dig(t, t, 1); + fp_hlv(t, t); +#if WSIZE == 8 + bn_set_dig(_t, d >> 8); + bn_lsh(_t, _t, 8); + bn_add_dig(_t, _t, d & 0xFF); +#else + bn_set_dig(_t, d); +#endif + fp_exp(t, t, _t); + + fp_mul(c, v, t); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT) } RLC_FINALLY { bn_free(_t); - dv_free(f); - dv_free(g); - dv_free(t); - dv_free(u); + fp_free(f); + fp_free(g); + fp_free(t); + fp_free(u); fp_free(v); fp_free(r); - fp_free(precomp); + } +} + +#endif + +#if FP_INV == JMPDS || !defined(STRIP) + +static dis_t jumpdivstep(dis_t m[4], dis_t delta, dig_t f, dig_t g, int s) { + dig_t u = 1, v = 0, q = 0, r = 1, c0, c1; + + /* This is actually faster than my previous version, several tricks from + * https://github.com/bitcoin-core/secp256k1/blob/master/src/modinv64_impl.h + */ + for (s--; s >= 0; s--) { + /* First handle the else part: if delta < 0, compute -(f,u,v). */ + c0 = delta >> (RLC_DIG - 1); + c1 = -(g & 1); + c0 &= c1; + /* Conditionally add -(f,u,v) to (g,q,r) */ + g += ((f ^ c0) - c0) & c1; + q += ((u ^ c0) - c0) & c1; + r += ((v ^ c0) - c0) & c1; + /* Now handle the 'if' part, so c0 will be (delta < 0) && (g & 1)) */ + /* delta = RLC_SEL(delta, -delta, c0 & 1) - 2 (for half-divstep), thus + * delta = - delta - 2 or delta - 1 */ + delta = (delta ^ c0) - 1; + f = f + (g & c0); + u = u + (q & c0); + v = v + (r & c0); + g >>= 1; + u += u; + v += v; + } + m[0] = u; + m[1] = v; + m[2] = q; + m[3] = r; + return delta; +} + +static inline void bn_mul2_low(dig_t *c, const dig_t *a, dis_t digit, int size) { + int sd = digit >> (RLC_DIG - 1); + digit = (digit ^ sd) - sd; + c[size] = bn_mul1_low(c, a, digit, size); +} + +void fp_inv_jmpds(fp_t c, const fp_t a) { + dis_t m[4]; + /* Compute number of iterations based on modulus size. */ + int i, d = -1, s = RLC_DIG - 2; + /* Iterations taken directly from https://github.com/sipa/safegcd-bounds */ + int iterations = (45907 * FP_PRIME + 26313) / 19929; + dv_t f, g, t, p, t0, t1, u0, u1, v0, v1, p01, p11; + fp_t pre; + + dv_null(f); + dv_null(g); + dv_null(t); + dv_null(p); + dv_null(t0); + dv_null(t1); + dv_null(u0); + dv_null(u1); + dv_null(v0); + dv_null(v1); + dv_null(p01); + dv_null(p11); + fp_null(pre); + + RLC_TRY { + dv_new(t0); + dv_new(f); + dv_new(t); + dv_new(p); + dv_new(g); + dv_new(t1); + dv_new(u0); + dv_new(u1); + dv_new(v0); + dv_new(v1); + dv_new(p01); + dv_new(p11); + fp_new(pre); + +#if (FP_PRIME % WSIZE) != 0 + int j = 0; + fp_copy(pre, core_get()->inv.dp); +#else + fp_copy(pre, core_get()->conv.dp); + fp_mul(pre, pre, core_get()->conv.dp); + fp_mul(pre, pre, core_get()->inv.dp); +#endif + + f[RLC_FP_DIGS] = g[RLC_FP_DIGS] = 0; + dv_zero(t, 2 * RLC_FP_DIGS); + dv_zero(p, 2 * RLC_FP_DIGS); + dv_zero(u0, 2 * RLC_FP_DIGS); + dv_zero(u1, 2 * RLC_FP_DIGS); + dv_zero(v0, 2 * RLC_FP_DIGS); + dv_zero(v1, 2 * RLC_FP_DIGS); + + dv_copy(f, fp_prime_get(), RLC_FP_DIGS); + dv_copy(p + 1, fp_prime_get(), RLC_FP_DIGS); +#if FP_RDC == MONTY + /* Convert a from Montgomery form. */ + fp_copy(t, a); + fp_rdcn_low(g, t); +#else + fp_copy(g, a); +#endif + d = jumpdivstep(m, d, f[0] & RLC_MASK(s), g[0] & RLC_MASK(s), s); + + t0[RLC_FP_DIGS] = bn_muls_low(t0, f, RLC_POS, m[0], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, RLC_POS, m[1], RLC_FP_DIGS); + bn_addn_low(t0, t0, t1, RLC_FP_DIGS + 1); + + f[RLC_FP_DIGS] = bn_muls_low(f, f, RLC_POS, m[2], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, RLC_POS, m[3], RLC_FP_DIGS); + bn_addn_low(t1, t1, f, RLC_FP_DIGS + 1); + + /* Update f and g. */ + bn_rshs_low(f, t0, RLC_FP_DIGS + 1, s); + bn_rshs_low(g, t1, RLC_FP_DIGS + 1, s); + + /* Update column vector below. */ + v1[0] = RLC_SEL(m[1], -m[1], RLC_SIGN(m[1])); + fp_negm_low(t, v1); + dv_copy_cond(v1, t, RLC_FP_DIGS, RLC_SIGN(m[1])); + u1[0] = RLC_SEL(m[3], -m[3], RLC_SIGN(m[3])); + fp_negm_low(t, u1); + dv_copy_cond(u1, t, RLC_FP_DIGS, RLC_SIGN(m[3])); + + dv_copy(p01, v1, 2 * RLC_FP_DIGS); + dv_copy(p11, u1, 2 * RLC_FP_DIGS); + + int loops = iterations / s; + loops = (iterations % s == 0 ? loops - 1 : loops); + + for (i = 1; i < loops; i++) { + d = jumpdivstep(m, d, f[0] & RLC_MASK(s), g[0] & RLC_MASK(s), s); + + t0[RLC_FP_DIGS] = bn_muls_low(t0, f, RLC_SIGN(f[RLC_FP_DIGS]), m[0], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, RLC_SIGN(g[RLC_FP_DIGS]), m[1], RLC_FP_DIGS); + bn_addn_low(t0, t0, t1, RLC_FP_DIGS + 1); + + f[RLC_FP_DIGS] = bn_muls_low(f, f, RLC_SIGN(f[RLC_FP_DIGS]), m[2], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, RLC_SIGN(g[RLC_FP_DIGS]), m[3], RLC_FP_DIGS); + bn_addn_low(t1, t1, f, RLC_FP_DIGS + 1); + + /* Update f and g. */ + bn_rshs_low(f, t0, RLC_FP_DIGS + 1, s); + bn_rshs_low(g, t1, RLC_FP_DIGS + 1, s); + +#if (FP_PRIME % WSIZE) != 0 + p[j] = 0; + dv_copy(p + j + 1, fp_prime_get(), RLC_FP_DIGS); + + /* Update column vector below. */ + bn_mul2_low(v0, p01, m[0], RLC_FP_DIGS + j); + fp_subd_low(t, p, v0); + dv_copy_cond(v0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[0])); + + bn_mul2_low(v1, p11, m[1], RLC_FP_DIGS + j); + fp_subd_low(t, p, v1); + dv_copy_cond(v1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[1])); + + bn_mul2_low(u0, p01, m[2], RLC_FP_DIGS + j); + fp_subd_low(t, p, u0); + dv_copy_cond(u0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[2])); + + bn_mul2_low(u1, p11, m[3], RLC_FP_DIGS + j); + fp_subd_low(t, p, u1); + dv_copy_cond(u1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[3])); + + j = i % RLC_FP_DIGS; + if (j == 0) { + fp_addd_low(t, u0, u1); + fp_rdcn_low(p11, t); + fp_addd_low(t, v0, v1); + fp_rdcn_low(p01, t); + dv_zero(v0, 2 * RLC_FP_DIGS); + dv_zero(v1, 2 * RLC_FP_DIGS); + } else { + fp_addd_low(p11, u0, u1); + fp_addd_low(p01, v0, v1); + } +#else + fp_zero(p); + dv_copy(p + RLC_FP_DIGS, fp_prime_get(), RLC_FP_DIGS); + + /* Update column vector below. */ + bn_mul2_low(v0, p01, m[0], 2 * RLC_FP_DIGS); + fp_subd_low(t, p, v0); + dv_copy_cond(v0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[0])); + + bn_mul2_low(v1, p11, m[1], 2 * RLC_FP_DIGS); + fp_subd_low(t, p, v1); + dv_copy_cond(v1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[1])); + + bn_mul2_low(u0, p01, m[2], 2 * RLC_FP_DIGS); + fp_subd_low(t, p, u0); + dv_copy_cond(u0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[2])); + + bn_mul2_low(u1, p11, m[3], 2 * RLC_FP_DIGS); + fp_subd_low(t, p, u1); + dv_copy_cond(u1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[3])); + + fp_addc_low(t, u0, u1); + fp_rdcn_low(p11, t); + fp_addc_low(t, v0, v1); + fp_rdcn_low(p01, t); + fp_mulm_low(pre, pre, core_get()->conv.dp); +#endif + } + + s = iterations - loops * s; + d = jumpdivstep(m, d, f[0] & RLC_MASK(s), g[0] & RLC_MASK(s), s); + + t0[RLC_FP_DIGS] = bn_muls_low(t0, f, RLC_SIGN(f[RLC_FP_DIGS]), m[0], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, RLC_SIGN(g[RLC_FP_DIGS]), m[1], RLC_FP_DIGS); + bn_addn_low(t0, t0, t1, RLC_FP_DIGS + 1); + + f[RLC_FP_DIGS] = bn_muls_low(f, f, RLC_SIGN(f[RLC_FP_DIGS]), m[2], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, RLC_SIGN(g[RLC_FP_DIGS]), m[3], RLC_FP_DIGS); + bn_addn_low(t1, t1, f, RLC_FP_DIGS + 1); + + /* Update f and g. */ + bn_rshs_low(f, t0, RLC_FP_DIGS + 1, s); + bn_rshs_low(g, t1, RLC_FP_DIGS + 1, s); + +#if (FP_PRIME % WSIZE) != 0 + p[j] = 0; + dv_copy(p + j + 1, fp_prime_get(), RLC_FP_DIGS); + + /* Update column vector below. */ + /* Update column vector below. */ + bn_mul2_low(v0, p01, m[0], RLC_FP_DIGS + j); + fp_subd_low(t, p, v0); + dv_copy_cond(v0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[0])); + + bn_mul2_low(v1, p11, m[1], RLC_FP_DIGS + j); + fp_subd_low(t, p, v1); + dv_copy_cond(v1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[1])); + + fp_addd_low(t, v0, v1); + fp_rdcn_low(p01, t); +#else + fp_zero(p); + dv_copy(p + RLC_FP_DIGS, fp_prime_get(), RLC_FP_DIGS); + + /* Update column vector below. */ + bn_mul2_low(v0, p01, m[0], 2 * RLC_FP_DIGS); + fp_subd_low(t, p, v0); + dv_copy_cond(v0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[0])); + + bn_mul2_low(v1, p11, m[1], 2 * RLC_FP_DIGS); + fp_subd_low(t, p, v1); + dv_copy_cond(v1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[1])); + + fp_addc_low(t, v0, v1); + fp_rdcn_low(p01, t); +#endif + + /* Negate based on sign of f at the end. */ + fp_negm_low(t, p01); + dv_copy_cond(p01, t, RLC_FP_DIGS, f[RLC_FP_DIGS] >> (RLC_DIG - 1)); + /* Multiply by (precomp * R^j) % p, one for each iteration of the loop, + * one for the constant, one more to be removed by reduction. */ + fp_mul(c, p01, pre); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + dv_free(t0); + dv_free(f); + dv_free(t); + dv_free(p); + dv_free(g); + dv_free(t1); + dv_free(u0); + dv_free(u1); + dv_free(v0); + dv_free(v1); + dv_free(p01); + dv_free(p11); + fp_free(pre); } } diff --git a/contrib/relic/src/fp/relic_fp_mul.c b/contrib/relic/src/fp/relic_fp_mul.c index bdfbe43cd..a9cf0aa67 100644 --- a/contrib/relic/src/fp/relic_fp_mul.c +++ b/contrib/relic/src/fp/relic_fp_mul.c @@ -137,7 +137,9 @@ static void fp_mul_karat_imp(dv_t c, const fp_t a, const fp_t b, int size, c += h; carry = bn_addn_low(c, c, t, 2 * (h1 + 1)); c += 2 * (h1 + 1); - bn_add1_low(c, c, carry, 2 * size - h - 2 * (h1 + 1)); + if (2 * size > h + 2 * (h1 + 1)) { + bn_add1_low(c, c, carry, 2 * size - h - 2 * (h1 + 1)); + } } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -216,7 +218,7 @@ void fp_mul_comba(fp_t c, const fp_t a, const fp_t b) { dv_new(t); fp_muln_low(t, a, b); - fp_rdcn_low(c, t); + fp_rdc(c, t); dv_free(t); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/fp/relic_fp_param.c b/contrib/relic/src/fp/relic_fp_param.c index b20aca22d..ffc8b55f6 100644 --- a/contrib/relic/src/fp/relic_fp_param.c +++ b/contrib/relic/src/fp/relic_fp_param.c @@ -247,6 +247,18 @@ void fp_param_set(int param) { bn_neg(t0, t0); fp_prime_set_pairf(t0, EP_BN); break; + case SM9_256: + /* x = 0x600000000058F98A */ + bn_set_2b(t0, 62); + bn_set_bit(t0, 61, 1); + bn_set_dig(t1, 0x58); + bn_lsh(t1, t1, 8); + bn_add_dig(t1, t1, 0xF9); + bn_lsh(t1, t1, 8); + bn_add(t0, t0, t1); + bn_add_dig(t0, t0, 0x8A); + fp_prime_set_pairf(t0, EP_BN); + break; #elif FP_PRIME == 381 case B12_381: /* x = -(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16). */ @@ -282,6 +294,15 @@ void fp_param_set(int param) { bn_sub_dig(p, p, 187); fp_prime_set_dense(p); break; + case B12_383: + /* x = 2^64 + 2^51 + 2^24 + 2^12 + 2^9 */ + bn_set_2b(t0, 64); + bn_set_bit(t0, 51, 1); + bn_set_bit(t0, 24, 1); + bn_set_bit(t0, 12, 1); + bn_set_bit(t0, 9, 1); + fp_prime_set_pairf(t0, EP_B12); + break; #elif FP_PRIME == 384 case NIST_384: /* p = 2^384 - 2^128 - 2^96 + 2^32 - 1. */ @@ -313,6 +334,14 @@ void fp_param_set(int param) { bn_neg(t0, t0); fp_prime_set_pairf(t0, EP_B12); break; +#elif FP_PRIME == 448 + case PRIME_448: + /* p = 2^448 - 2^224 + 1. */ + f[0] = -1; + f[1] = -224; + f[2] = 448; + fp_prime_set_pmers(f, 3); + break; #elif FP_PRIME == 455 case B12_455: /* x = 2^76 + 2^53 + 2^31 + 2^11. */ @@ -322,30 +351,6 @@ void fp_param_set(int param) { bn_set_bit(t0, 11, 1); fp_prime_set_pairf(t0, EP_B12); break; -#elif FP_PRIME == 477 - case B24_477: - /* x = -2^48 + 2^45 + 2^31 - 2^7. */ - bn_set_2b(t0, 48); - bn_set_2b(t1, 45); - bn_sub(t0, t0, t1); - bn_set_2b(t1, 31); - bn_sub(t0, t0, t1); - bn_set_2b(t1, 7); - bn_add(t0, t0, t1); - bn_neg(t0, t0); - /* p = (u - 1)^2 * (u^8 - u^4 + 1) div 3 + u. */ - bn_sub_dig(p, t0, 1); - bn_sqr(p, p); - bn_sqr(t1, t0); - bn_sqr(t1, t1); - bn_sqr(t2, t1); - bn_sub(t2, t2, t1); - bn_add_dig(t2, t2, 1); - bn_mul(p, p, t2); - bn_div_dig(p, p, 3); - bn_add(p, p, t0); - fp_prime_set_dense(p); - break; #elif FP_PRIME == 508 case KSS_508: /* x = -(2^64 + 2^51 - 2^46 - 2^12). */ @@ -386,6 +391,18 @@ void fp_param_set(int param) { bn_sub_dig(p, p, 1); fp_prime_set_dense(p); break; +#elif FP_PRIME == 509 + case B24_509: + /* x = -2^51 - 2^28 + 2^11 - 1. */ + bn_set_2b(t0, 51); + bn_set_2b(t1, 28); + bn_add(t0, t0, t1); + bn_set_2b(t1, 11); + bn_sub(t0, t0, t1); + bn_add_dig(t0, t0, 1); + bn_neg(t0, t0); + fp_prime_set_pairf(t0, EP_B24); + break; #elif FP_PRIME == 511 case OT_511: bn_set_2b(t0, 52); @@ -406,7 +423,7 @@ void fp_param_set(int param) { fp_prime_set_pmers(f, 2); break; #elif FP_PRIME == 544 - case CP8_544: + case GMT8_544: bn_read_str(p, STR_P544, strlen(STR_P544), 16); /* T = 2^64 - 2^54 + 2^37 + 2^32 - 4 */ bn_set_2b(t0, 64); @@ -417,7 +434,7 @@ void fp_param_set(int param) { bn_set_2b(t1, 32); bn_add(t0, t0, t1); bn_sub_dig(t0, t0, 4); - fp_prime_set_pairf(t0, EP_CP8); + fp_prime_set_pairf(t0, EP_GMT8); fp_prime_set_dense(p); break; #elif FP_PRIME == 569 @@ -572,6 +589,8 @@ int fp_param_set_any_pmers(void) { fp_param_set(NIST_256); #elif FP_PRIME == 384 fp_param_set(NIST_384); +#elif FP_PRIME == 448 + fp_param_set(PRIME_448); #elif FP_PRIME == 521 fp_param_set(NIST_521); #else @@ -600,6 +619,8 @@ int fp_param_set_any_tower(void) { fp_param_set(B12_381); #elif FP_PRIME == 382 fp_param_set(BN_382); +#elif FP_PRIME == 383 + fp_param_set(B12_383); #elif FP_PRIME == 446 #ifdef FP_QNRES fp_param_set(B12_446); @@ -608,14 +629,14 @@ int fp_param_set_any_tower(void) { #endif #elif FP_PRIME == 455 fp_param_set(B12_455); -#elif FP_PRIME == 477 - fp_param_set(B24_477); #elif FP_PRIME == 508 fp_param_set(KSS_508); +#elif FP_PRIME == 509 + fp_param_set(B24_509); #elif FP_PRIME == 511 fp_param_set(OT_511); #elif FP_PRIME == 544 - fp_param_set(CP8_544); + fp_param_set(GMT8_544); #elif FP_PRIME == 569 fp_param_set(K54_569); #elif FP_PRIME == 575 diff --git a/contrib/relic/src/fp/relic_fp_prime.c b/contrib/relic/src/fp/relic_fp_prime.c index 6b8c60843..7cbdbcb29 100644 --- a/contrib/relic/src/fp/relic_fp_prime.c +++ b/contrib/relic/src/fp/relic_fp_prime.c @@ -63,24 +63,60 @@ static void fp_prime_set(const bn_t p) { bn_copy(&(ctx->prime), p); - #if FP_RDC == MONTY || !defined(STRIP) +#if FP_RDC == MONTY || !defined(STRIP) bn_mod_pre_monty(t, &(ctx->prime)); ctx->u = t->dp[0]; /* compute R mod p */ bn_set_dig(&(ctx->one), 1); - bn_lsh(&(ctx->one), &(ctx->one), ctx->prime.used * RLC_DIG); + bn_lsh(&(ctx->one), &(ctx->one), RLC_FP_DIGS * RLC_DIG); bn_mod(&(ctx->one), &(ctx->one), &(ctx->prime)); /* compute the R^2 mod p */ fp_add(r, ctx->one.dp, ctx->one.dp); - bn_set_dig(t, RLC_FP_DIGS * RLC_DIG); - fp_exp(ctx->conv.dp, r, t ); + bn_set_dig(t, RLC_FP_DIGS); + bn_lsh(t, t, RLC_DIG_LOG); + fp_exp(ctx->conv.dp, r, t); ctx->conv.used = RLC_FP_DIGS; bn_trim(&(ctx->conv)); - #endif /* FP_RDC == MONTY */ +#endif /* FP_RDC == MONTY */ + +#if FP_INV == JUMPDS || !defined(STRIP) + + int d = (45907 * FP_PRIME + 26313) / 19929; + +#if WSIZE == 8 + bn_set_dig(t, d >> 8); + bn_lsh(t, t, 8); + bn_add_dig(t, t, d & 0xFF); +#else + bn_set_dig(t, d); +#endif + ctx->inv.used = RLC_FP_DIGS; + dv_copy(ctx->inv.dp, fp_prime_get(), RLC_FP_DIGS); + fp_add_dig(ctx->inv.dp, ctx->inv.dp, 1); + fp_hlv(ctx->inv.dp, ctx->inv.dp); + fp_exp(ctx->inv.dp, ctx->inv.dp, t); + +#if FP_RDC == MONTY + +#if (FP_PRIME % WSIZE) != 0 + fp_mul(ctx->inv.dp, ctx->inv.dp, ctx->conv.dp); + fp_mul(ctx->inv.dp, ctx->inv.dp, ctx->conv.dp); + + for (int i = 1, j = 0; i < d / (RLC_DIG - 2); i++) { + j = i % RLC_FP_DIGS; + if (j == 0) { + fp_mulm_low(ctx->inv.dp, ctx->inv.dp, ctx->conv.dp); + } + } +#endif + +#endif /* FP_RDC == MONTY */ + +#endif /* FP_INV */ /* Now look for proper quadratic/cubic non-residues. */ ctx->qnr = ctx->cnr = 0; @@ -146,16 +182,19 @@ static void fp_prime_set(const bn_t p) { void fp_prime_init(void) { ctx_t *ctx = core_get(); ctx->fp_id = 0; - bn_init(&(ctx->prime), RLC_FP_DIGS); - bn_init(&(ctx->par), RLC_FP_DIGS); + bn_make(&(ctx->prime), RLC_FP_DIGS); + bn_make(&(ctx->par), RLC_FP_DIGS); #if FP_RDC == QUICK || !defined(STRIP) ctx->sps_len = 0; memset(ctx->sps, 0, sizeof(ctx->sps)); #endif #if FP_RDC == MONTY || !defined(STRIP) - bn_init(&(ctx->conv), RLC_FP_DIGS); - bn_init(&(ctx->one), RLC_FP_DIGS); + bn_make(&(ctx->conv), RLC_FP_DIGS); + bn_make(&(ctx->one), RLC_FP_DIGS); #endif +#if FP_INV == JUMPDS || !defined(STRIP) + bn_make(&(ctx->inv), RLC_FP_DIGS); +#endif /* FP_INV */ } void fp_prime_clean(void) { @@ -170,6 +209,9 @@ void fp_prime_clean(void) { bn_clean(&(ctx->one)); bn_clean(&(ctx->conv)); #endif +#if FP_INV == JUMPDS || !defined(STRIP) + bn_clean(&(ctx->inv)); +#endif /* FP_INV */ bn_clean(&(ctx->prime)); bn_clean(&(ctx->par)); } @@ -322,6 +364,20 @@ void fp_prime_set_pairf(const bn_t x, int pairf) { bn_div_dig(p, p, 4); fp_prime_set_dense(p); break; + case EP_B24: + /* p = (x - 1)^2 * (x^8 - x^4 + 1)/3 + x. */ + bn_sqr(t1, t0); + bn_sqr(t1, t1); + bn_sqr(p, t1); + bn_sub(p, p, t1); + bn_add_dig(p, p, 1); + bn_sub_dig(t1, t0, 1); + bn_sqr(t1, t1); + bn_mul(p, p, t1); + bn_div_dig(p, p, 3); + bn_add(p, p, t0); + fp_prime_set_dense(p); + break; case EP_B48: /* p = (x - 1)^2*(x^16 - x^8 + 1) / 3 + x. */ bn_sqr(t1, t0); @@ -458,6 +514,7 @@ void fp_prime_calc(void) { #ifdef WITH_FPX if (fp_prime_get_qnr() != 0) { fp2_field_init(); + fp4_field_init(); } if (fp_prime_get_cnr() != 0) { fp3_field_init(); diff --git a/contrib/relic/src/fp/relic_fp_smb.c b/contrib/relic/src/fp/relic_fp_smb.c new file mode 100644 index 000000000..ee42147a5 --- /dev/null +++ b/contrib/relic/src/fp/relic_fp_smb.c @@ -0,0 +1,326 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of Legendre and Jacobi symbols for prime fields. + * + * @ingroup fp + */ + +#include "relic_core.h" +#include "relic_bn_low.h" +#include "relic_fp_low.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +#if FP_SMB == BASIC || !defined(STRIP) + +int fp_smb_basic(const fp_t a) { + bn_t t; + int r = 0; + + bn_null(t); + + RLC_TRY { + bn_new(t); + + /* t = (b - 1)/2. */ + t->sign = RLC_POS; + t->used = RLC_FP_DIGS; + dv_copy(t->dp, fp_prime_get(), RLC_FP_DIGS); + bn_sub_dig(t, t, 1); + bn_hlv(t, t); + + fp_exp(t->dp, a, t); + r = (fp_cmp_dig(t->dp, 1) == RLC_EQ); + fp_neg(t->dp, t->dp); + r = RLC_SEL(r, -(fp_cmp_dig(t->dp, 1) == RLC_EQ), !r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(t); + } + return r; +} + +#endif + +#if FP_SMB == DIVST || !defined(STRIP) + +int fp_smb_divst(const fp_t a) { + /* Compute number of iterations based on modulus size. */ +#if FP_PRIME < 46 + int r, d = (49 * FP_PRIME + 80)/17; +#else + int r, d = (49 * FP_PRIME + 57)/17; +#endif + dig_t delta = 1, g0, d0, fs, gs, k, mask, s; + bn_t _t; + dv_t f, g, t; + + bn_null(_t); + dv_null(f); + dv_null(g); + dv_null(t); + + RLC_TRY { + bn_new(_t); + dv_new(f); + dv_new(g); + dv_new(t); + +#if WSIZE == 8 + bn_set_dig(_t, d >> 8); + bn_lsh(_t, _t, 8); + bn_add_dig(_t, _t, d & 0xFF); +#else + bn_set_dig(_t, d); +#endif + + k = 0; + fp_prime_back(_t, a); + dv_zero(g, RLC_FP_DIGS); + dv_copy(g, _t->dp, _t->used); + dv_copy(f, fp_prime_get(), RLC_FP_DIGS); + fs = gs = RLC_POS; + + for (int i = 0; i < d; i++) { + d0 = g[0] & ((int)delta > 0); + /* Conditionally negate delta if d0 is set. */ + delta = (delta ^ -d0) + d0; + k ^= (((g[0] >> (dig_t)1) & ((f[0] >> (dig_t)1) ^ 1)) ^ (~fs & gs)) & d0; + + /* Conditionally swap and negate based on d0. */ + mask = -d0; + s = (fs ^ gs) & mask; + fs ^= s; + gs ^= s ^ d0; + for (int j = 0; j < RLC_FP_DIGS; j++) { + s = (f[j] ^ g[j]) & mask; + f[j] ^= s; + g[j] ^= s ^ (-d0); + } + fp_add1_low(g, g, d0); + + k ^= (f[0] >> 1) ^ (f[0] >> 2); + k &= 1; + + delta++; + g0 = g[0] & 1; + for (int j = 0; j < RLC_FP_DIGS; j++) { + t[j] = f[j] & (-g0); + } + + /* Compute g = (g + g0*f) div 2 by conditionally copying f to u and + * updating the sign of g. */ + gs ^= g0 & (fs ^ bn_addn_low(g, g, t, RLC_FP_DIGS)); + /* Shift and restore the sign. */ + fp_rsh1_low(g, g); + g[RLC_FP_DIGS - 1] |= (dig_t)gs << (RLC_DIG - 1); + } + + for (int j = 0; j < RLC_FP_DIGS; j++) { + t[j] = 0; + f[j] ^= -fs; + } + t[0] = 1; + fp_add1_low(f, f, fs); + + r = !(dv_cmp_const(f, t, RLC_FP_DIGS) == RLC_NE); + r = RLC_SEL(r, -1, (r == 1 && k == 1)); + r = RLC_SEL(r, 1, (r == 1 && k == 0)); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT) + } RLC_FINALLY { + bn_free(_t); + dv_free(f); + dv_free(g); + dv_free(t); + } + return r; +} + +#endif + +#if FP_SMB == JMPDS || !defined(STRIP) + +static dis_t jumpdivstep(dis_t m[4], dig_t *k, dis_t delta, dis_t x, dis_t y, int s) { + dig_t c0, c1, yi, ai = 1, bi = 0, ci = 0, di = 1, u = 0; + for (; s > 0; s--) { + yi = y; + + c0 = ~(delta >> (RLC_DIG - 1)); + c1 = -(x & 1); + c0 &= c1; + + x += ((y ^ c0) - c0) & c1; + ai += ((ci ^ c0) - c0) & c1; + bi += ((di ^ c0) - c0) & c1; + + /* delta = RLC_SEL(delta + 1, -delta, c0) */ + delta = (delta ^ c0) + 1; + y = y + (x & c0); + ci = ci + (ai & c0); + di = di + (bi & c0); + x >>= 1; + ci += ci; + di += di; + + u += ((yi & y) ^ (y >> (dig_t)1)) & 2; + u += (u & (dig_t)1) ^ (ci >> (dig_t)(RLC_DIG - 1)); + u %= 4; + } + m[0] = ai; + m[1] = bi; + m[2] = ci; + m[3] = di; + *k = u; + return delta; +} + +int fp_smb_jmpds(const fp_t a) { + dis_t m[4], d = 0; + int r, i, s = RLC_DIG - 2; + /* Iterations taken directly from https://github.com/sipa/safegcd-bounds */ + int loops, iterations = (45907 * FP_PRIME + 26313) / 19929; + dv_t f, g, t, p, t0, t1, u0, u1, v0, v1, p01, p11; + dig_t j, k, mask = RLC_MASK(s + 2); + + dv_null(f); + dv_null(g); + dv_null(t); + dv_null(p); + dv_null(t0); + dv_null(t1); + dv_null(u0); + dv_null(u1); + dv_null(v0); + dv_null(v1); + dv_null(p01); + dv_null(p11); + + RLC_TRY { + dv_new(t0); + dv_new(f); + dv_new(t); + dv_new(p); + dv_new(g); + dv_new(t1); + dv_new(u0); + dv_new(u1); + dv_new(v0); + dv_new(v1); + dv_new(p01); + dv_new(p11); + + f[RLC_FP_DIGS] = g[RLC_FP_DIGS] = 0; + dv_zero(f, 2 * RLC_FP_DIGS); + dv_zero(g, 2 * RLC_FP_DIGS); + dv_zero(t, 2 * RLC_FP_DIGS); + dv_zero(p, 2 * RLC_FP_DIGS); + dv_zero(u0, 2 * RLC_FP_DIGS); + dv_zero(u1, 2 * RLC_FP_DIGS); + dv_zero(v0, 2 * RLC_FP_DIGS); + dv_zero(v1, 2 * RLC_FP_DIGS); + + dv_copy(g, fp_prime_get(), RLC_FP_DIGS); +#if FP_RDC == MONTY + /* Convert a from Montgomery form. */ + fp_copy(t, a); + fp_rdcn_low(f, t); +#else + fp_copy(f, a); +#endif + + loops = iterations / s; + loops = (iterations % s == 0 ? loops - 1 : loops); + + j = k = 0; + for (i = 0; i <= loops; i++) { + d = jumpdivstep(m, &k, d, f[0] & mask, g[0] & mask, s); + + t0[RLC_FP_DIGS] = bn_muls_low(t0, f, f[RLC_FP_DIGS] >> (RLC_DIG - 1), m[0], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, g[RLC_FP_DIGS] >> (RLC_DIG - 1), m[1], RLC_FP_DIGS); + bn_addn_low(t0, t0, t1, RLC_FP_DIGS + 1); + + f[RLC_FP_DIGS] = bn_muls_low(f, f, f[RLC_FP_DIGS] >> (RLC_DIG - 1), m[2], RLC_FP_DIGS); + t1[RLC_FP_DIGS] = bn_muls_low(t1, g, g[RLC_FP_DIGS] >> (RLC_DIG - 1), m[3], RLC_FP_DIGS); + bn_addn_low(t1, t1, f, RLC_FP_DIGS + 1); + + /* Update f and g. */ + bn_rshs_low(f, t0, RLC_FP_DIGS + 1, s); + bn_rshs_low(g, t1, RLC_FP_DIGS + 1, s); + + j = (j + k) % 4; + j = (j + ((j & 1) ^ (g[RLC_FP_DIGS] >> (RLC_DIG - 1)))) % 4; + } + + r = 0; + j = (j + (j & 1)) % 4; + + fp_zero(t0); + t0[0] = 1; + r = RLC_SEL(r, 1 - j, dv_cmp_const(g, t0, RLC_FP_DIGS) == RLC_EQ); + for (i = 0; i < RLC_FP_DIGS; i++) { + g[i] = ~g[i]; + } + bn_add1_low(g, g, 1, RLC_FP_DIGS); + r = RLC_SEL(r, 1 - j, dv_cmp_const(g, t0, RLC_FP_DIGS) == RLC_EQ); + r = RLC_SEL(r, 1 - j, fp_is_zero(g)); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + dv_free(t0); + dv_free(f); + dv_free(t); + dv_free(p); + dv_free(g); + dv_free(t1); + dv_free(u0); + dv_free(u1); + dv_free(v0); + dv_free(v1); + dv_free(p01); + dv_free(p11); + } + + return r; +} + +#endif + +#if FP_SMB == LOWER || !defined(STRIP) + +int fp_smb_lower(const fp_t a) { + return fp_smbm_low(a); +} + +#endif diff --git a/contrib/relic/src/fp/relic_fp_sqr.c b/contrib/relic/src/fp/relic_fp_sqr.c index b79717a6d..2d2f83be0 100644 --- a/contrib/relic/src/fp/relic_fp_sqr.c +++ b/contrib/relic/src/fp/relic_fp_sqr.c @@ -140,7 +140,9 @@ static void fp_sqr_karat_imp(dv_t c, const fp_t a, int size, int level) { c += h; carry = bn_addn_low(c, c, t1, 2 * (h1 + 1)); c += 2 * (h1 + 1); - carry = bn_add1_low(c, c, carry, 2 * size - h - 2 * (h1 + 1)); + if (2 * size > h + 2 * (h1 + 1)) { + carry = bn_add1_low(c, c, carry, 2 * size - h - 2 * (h1 + 1)); + } } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/fp/relic_fp_util.c b/contrib/relic/src/fp/relic_fp_util.c index 10ce01401..84d2c50ac 100644 --- a/contrib/relic/src/fp/relic_fp_util.c +++ b/contrib/relic/src/fp/relic_fp_util.c @@ -240,14 +240,20 @@ void fp_read_bin(fp_t a, const uint8_t *bin, int len) { RLC_TRY { bn_new(t); bn_read_bin(t, bin, len); - if (bn_is_zero(t)) { - fp_zero(a); + + /* Reject values out of bounds. */ + if (bn_sign(t) == RLC_NEG || bn_cmp(t, &core_get()->prime) != RLC_LT) { + RLC_THROW(ERR_NO_VALID); } else { - if (t->used == 1) { - fp_prime_conv_dig(a, t->dp[0]); + if (bn_is_zero(t)) { + fp_zero(a); } else { - fp_prime_conv(a, t); - } + if (t->used == 1) { + fp_prime_conv_dig(a, t->dp[0]); + } else { + fp_prime_conv(a, t); + } + } } } RLC_CATCH_ANY { diff --git a/contrib/relic/src/fpx/relic_fp24_sqr.c b/contrib/relic/src/fpx/relic_fp24_sqr.c index e6e800367..0e45d998c 100644 --- a/contrib/relic/src/fpx/relic_fp24_sqr.c +++ b/contrib/relic/src/fpx/relic_fp24_sqr.c @@ -111,6 +111,164 @@ void fp24_sqr_basic(fp24_t c, fp24_t a) { } } +void fp24_sqr_cyc_basic(fp24_t c, fp24_t a) { + fp4_t t0, t1, t2, t3, t4, t5, t6; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + fp4_null(t5); + fp4_null(t6); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + fp4_new(t5); + fp4_new(t6); + + fp4_sqr(t2, a[0][0]); + fp4_sqr(t3, a[0][1]); + fp4_add(t1, a[0][0], a[0][1]); + + fp4_mul_art(t0, t3); + fp4_add(t0, t0, t2); + + fp4_sqr(t1, t1); + fp4_sub(t1, t1, t2); + fp4_sub(t1, t1, t3); + + fp4_sub(c[0][0], t0, a[0][0]); + fp4_add(c[0][0], c[0][0], c[0][0]); + fp4_add(c[0][0], t0, c[0][0]); + + fp4_add(c[0][1], t1, a[0][1]); + fp4_add(c[0][1], c[0][1], c[0][1]); + fp4_add(c[0][1], t1, c[0][1]); + + fp4_sqr(t0, a[2][0]); + fp4_sqr(t1, a[2][1]); + fp4_add(t5, a[2][0], a[2][1]); + fp4_sqr(t2, t5); + + fp4_add(t3, t0, t1); + fp4_sub(t5, t2, t3); + + fp4_add(t6, a[1][0], a[1][1]); + fp4_sqr(t3, t6); + fp4_sqr(t2, a[1][0]); + + fp4_mul_art(t6, t5); + fp4_add(t5, t6, a[1][0]); + fp4_dbl(t5, t5); + fp4_add(c[1][0], t5, t6); + + fp4_mul_art(t4, t1); + fp4_add(t5, t0, t4); + fp4_sub(t6, t5, a[1][1]); + + fp4_sqr(t1, a[1][1]); + + fp4_dbl(t6, t6); + fp4_add(c[1][1], t6, t5); + + fp4_mul_art(t4, t1); + fp4_add(t5, t2, t4); + fp4_sub(t6, t5, a[2][0]); + fp4_dbl(t6, t6); + fp4_add(c[2][0], t6, t5); + + fp4_add(t0, t2, t1); + fp4_sub(t5, t3, t0); + fp4_add(t6, t5, a[2][1]); + fp4_dbl(t6, t6); + fp4_add(c[2][1], t5, t6); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + fp4_free(t5); + fp4_free(t6); + } +} + +void fp24_sqr_pck_basic(fp24_t c, fp24_t a) { + fp4_t t0, t1, t2, t3, t4, t5, t6; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + fp4_null(t5); + fp4_null(t6); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + fp4_new(t5); + fp4_new(t6); + + fp4_sqr(t0, a[2][0]); + fp4_sqr(t1, a[2][1]); + fp4_add(t5, a[2][0], a[2][1]); + fp4_sqr(t2, t5); + + fp4_add(t3, t0, t1); + fp4_sub(t5, t2, t3); + + fp4_add(t6, a[1][0], a[1][1]); + fp4_sqr(t3, t6); + fp4_sqr(t2, a[1][0]); + + fp4_mul_art(t6, t5); + fp4_add(t5, t6, a[1][0]); + fp4_dbl(t5, t5); + fp4_add(c[1][0], t5, t6); + + fp4_mul_art(t4, t1); + fp4_add(t5, t0, t4); + fp4_sub(t6, t5, a[1][1]); + + fp4_sqr(t1, a[1][1]); + + fp4_dbl(t6, t6); + fp4_add(c[1][1], t6, t5); + + fp4_mul_art(t4, t1); + fp4_add(t5, t2, t4); + fp4_sub(t6, t5, a[2][0]); + fp4_dbl(t6, t6); + fp4_add(c[2][0], t6, t5); + + fp4_add(t0, t2, t1); + fp4_sub(t5, t3, t0); + fp4_add(t6, t5, a[2][1]); + fp4_dbl(t6, t6); + fp4_add(c[2][1], t5, t6); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + fp4_free(t5); + fp4_free(t6); + } +} #endif @@ -239,4 +397,14 @@ void fp24_sqr_lazyr(fp24_t c, fp24_t a) { } } +void fp24_sqr_cyc_lazyr(fp24_t c, fp24_t a) { + /* TODO: implement lazy reduction. */ + fp24_sqr_cyc_basic(c, a); +} + +void fp24_sqr_pck_lazyr(fp24_t c, fp24_t a) { + /* TODO: implement lazy reduction. */ + fp24_sqr_pck_basic(c, a); +} + #endif diff --git a/contrib/relic/src/fpx/relic_fp4_mul.c b/contrib/relic/src/fpx/relic_fp4_mul.c index f44f1ef15..1ab92ea9e 100644 --- a/contrib/relic/src/fpx/relic_fp4_mul.c +++ b/contrib/relic/src/fpx/relic_fp4_mul.c @@ -166,3 +166,29 @@ void fp4_mul_art(fp4_t c, fp4_t a) { fp2_free(t0); } } + +void fp4_mul_frb(fp4_t c, fp4_t a, int i, int j) { + fp2_t t; + + fp2_null(t); + + RLC_TRY { + fp2_new(t); + + fp_copy(t[0], core_get()->fp4_p1[0]); + fp_copy(t[1], core_get()->fp4_p1[1]); + if (i == 1) { + for (int k = 0; k < j; k++) { + fp2_mul(c[0], a[0], t); + fp2_mul(c[1], a[1], t); + fp4_mul_art(c, c); + } + } else { + RLC_THROW(ERR_NO_VALID); + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp2_free(t); + } +} diff --git a/contrib/relic/src/fpx/relic_fpx_add.c b/contrib/relic/src/fpx/relic_fpx_add.c index 5607c9c96..ca1fbf8ce 100644 --- a/contrib/relic/src/fpx/relic_fpx_add.c +++ b/contrib/relic/src/fpx/relic_fpx_add.c @@ -89,19 +89,19 @@ void fp2_neg(fp2_t c, fp2_t a) { #if FPX_CBC == BASIC || !defined(STRIP) -void fp3_add_basic(fp2_t c, fp2_t a, fp2_t b) { +void fp3_add_basic(fp3_t c, fp3_t a, fp3_t b) { fp_add(c[0], a[0], b[0]); fp_add(c[1], a[1], b[1]); fp_add(c[2], a[2], b[2]); } -void fp3_sub_basic(fp2_t c, fp2_t a, fp2_t b) { +void fp3_sub_basic(fp3_t c, fp3_t a, fp3_t b) { fp_sub(c[0], a[0], b[0]); fp_sub(c[1], a[1], b[1]); fp_sub(c[2], a[2], b[2]); } -void fp3_dbl_basic(fp2_t c, fp2_t a) { +void fp3_dbl_basic(fp3_t c, fp3_t a) { /* 2 * (a_0 + a_1 * u) = 2 * a_0 + 2 * a_1 * u. */ fp_dbl(c[0], a[0]); fp_dbl(c[1], a[1]); @@ -118,15 +118,15 @@ void fp3_neg(fp3_t c, fp3_t a) { #if FPX_CBC == INTEG || !defined(STRIP) -void fp3_add_integ(fp2_t c, fp2_t a, fp2_t b) { +void fp3_add_integ(fp3_t c, fp3_t a, fp3_t b) { fp3_addm_low(c, a, b); } -void fp3_sub_integ(fp2_t c, fp2_t a, fp2_t b) { +void fp3_sub_integ(fp3_t c, fp3_t a, fp3_t b) { fp3_subm_low(c, a, b); } -void fp3_dbl_integ(fp2_t c, fp2_t a) { +void fp3_dbl_integ(fp3_t c, fp3_t a) { fp3_dblm_low(c, a); } diff --git a/contrib/relic/src/fpx/relic_fpx_cyc.c b/contrib/relic/src/fpx/relic_fpx_cyc.c index 8bbb68f74..5f8e0310f 100644 --- a/contrib/relic/src/fpx/relic_fpx_cyc.c +++ b/contrib/relic/src/fpx/relic_fpx_cyc.c @@ -32,138 +32,6 @@ #include "relic_core.h" -/*============================================================================*/ -/* Private definitions */ -/*============================================================================*/ - -void fp12_glv(bn_t _b[4], bn_t b) { - int i, l; - bn_t n, u[4], v[4]; - - bn_null(n); - - RLC_TRY { - bn_new(n); - for (i = 0; i < 4; i++) { - bn_null(u[i]); - bn_null(v[i]); - bn_new(u[i]); - bn_new(v[i]); - } - - ep_curve_get_ord(n); - - switch (ep_curve_is_pairf()) { - case EP_BN: - ep2_curve_get_vs(v); - - for (i = 0; i < 4; i++) { - bn_mul(v[i], v[i], b); - bn_div(v[i], v[i], n); - if (bn_sign(v[i]) == RLC_NEG) { - bn_add_dig(v[i], v[i], 1); - } - bn_zero(_b[i]); - } - - fp_prime_get_par(u[0]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[1], u[2], 1); - bn_sub_dig(u[3], u[0], 1); - bn_add_dig(u[0], u[0], 1); - bn_copy(_b[0], b); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_b[0], _b[0], n); - bn_sub(_b[0], _b[0], u[i]); - bn_mod(_b[0], _b[0], n); - } - - fp_prime_get_par(u[0]); - bn_neg(u[1], u[0]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[2], u[2], 1); - bn_dbl(u[3], u[2]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_b[1], _b[1], n); - bn_sub(_b[1], _b[1], u[i]); - bn_mod(_b[1], _b[1], n); - } - - fp_prime_get_par(u[0]); - bn_add_dig(u[1], u[0], 1); - bn_neg(u[1], u[1]); - bn_dbl(u[2], u[0]); - bn_add_dig(u[2], u[2], 1); - bn_sub_dig(u[3], u[2], 2); - bn_neg(u[3], u[3]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_b[2], _b[2], n); - bn_sub(_b[2], _b[2], u[i]); - bn_mod(_b[2], _b[2], n); - } - - fp_prime_get_par(u[1]); - bn_dbl(u[0], u[1]); - bn_neg(u[0], u[0]); - bn_dbl(u[2], u[1]); - bn_add_dig(u[2], u[2], 1); - bn_sub_dig(u[3], u[1], 1); - bn_neg(u[1], u[1]); - for (i = 0; i < 4; i++) { - bn_mul(u[i], u[i], v[i]); - bn_mod(u[i], u[i], n); - bn_add(_b[3], _b[3], n); - bn_sub(_b[3], _b[3], u[i]); - bn_mod(_b[3], _b[3], n); - } - - for (i = 0; i < 4; i++) { - l = bn_bits(_b[i]); - bn_sub(_b[i], n, _b[i]); - if (bn_bits(_b[i]) > l) { - bn_sub(_b[i], _b[i], n); - _b[i]->sign = RLC_POS; - } else { - _b[i]->sign = RLC_NEG; - } - } - break; - case EP_B12: - bn_abs(v[0], b); - fp_prime_get_par(u[0]); - - bn_copy(u[1], u[0]); - bn_abs(u[0], u[0]); - - for (i = 0; i < 4; i++) { - bn_mod(_b[i], v[0], u[0]); - bn_div(v[0], v[0], u[0]); - if ((bn_sign(u[1]) == RLC_NEG) && (i % 2 != 0)) { - bn_neg(_b[i], _b[i]); - } - if (bn_sign(b) == RLC_NEG) { - bn_neg(_b[i], _b[i]); - } - } - break; - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - bn_free(n); - for (i = 0; i < 4; i++) { - bn_free(u[i]); - bn_free(v[i]); - } - } -} - /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -216,11 +84,10 @@ int fp2_test_cyc(fp2_t a) { void fp2_exp_cyc(fp2_t c, fp2_t a, bn_t b) { fp2_t r, s, t[1 << (FP_WIDTH - 2)]; int i, l; - signed char naf[RLC_FP_BITS + 1], *k; + int8_t naf[RLC_FP_BITS + 1], *k; if (bn_is_zero(b)) { - fp2_set_dig(c, 1); - return; + return fp2_set_dig(c, 1); } fp2_null(r); @@ -327,11 +194,10 @@ int fp8_test_cyc(fp8_t a) { void fp8_exp_cyc(fp8_t c, fp8_t a, bn_t b) { fp8_t r, s, t[1 << (FP_WIDTH - 2)]; int i, l; - signed char naf[RLC_FP_BITS + 1], *k; + int8_t naf[RLC_FP_BITS + 1], *k; if (bn_is_zero(b)) { - fp8_set_dig(c, 1); - return; + return fp8_set_dig(c, 1); } fp8_null(r); @@ -516,6 +382,7 @@ void fp12_back_cyc_sim(fp12_t c[], fp12_t a[], int n) { *t2 = t + 2 * n; if (n == 0) { + RLC_FREE(t); return; } @@ -588,17 +455,23 @@ void fp12_back_cyc_sim(fp12_t c[], fp12_t a[], int n) { void fp12_exp_cyc(fp12_t c, fp12_t a, bn_t b) { int i, j, k, l, w = bn_ham(b); - bn_t _b[4]; if (bn_is_zero(b)) { - fp12_set_dig(c, 1); - return; + return fp12_set_dig(c, 1); } if ((bn_bits(b) > RLC_DIG) && ((w << 3) > bn_bits(b))) { + int _l[4]; + int8_t naf[4][RLC_FP_BITS + 1]; fp12_t t[4]; + bn_t _b[4], n, u; + + bn_null(n); + bn_null(u); RLC_TRY { + bn_new(n); + bn_new(u); for (i = 0; i < 4; i++) { bn_null(_b[i]); bn_new(_b[i]); @@ -606,24 +479,38 @@ void fp12_exp_cyc(fp12_t c, fp12_t a, bn_t b) { fp12_new(t[i]); } - fp12_glv(_b, b); + ep_curve_get_ord(n); + fp_prime_get_par(u); + bn_rec_frb(_b, 4, b, u, n, ep_curve_is_pairf() == EP_B12 || + ep_curve_is_pairf() == EP_B24 || ep_curve_is_pairf() == EP_B48); if (ep_curve_is_pairf()) { + fp12_copy(t[0], a); + fp12_frb(t[1], t[0], 1); + fp12_frb(t[2], t[1], 1); + fp12_frb(t[3], t[2], 1); + + l = 0; for (i = 0; i < 4; i++) { - fp12_frb(t[i], a, i); if (bn_sign(_b[i]) == RLC_NEG) { fp12_inv_cyc(t[i], t[i]); } + _l[i] = RLC_FP_BITS + 1; + bn_rec_naf(naf[i], &_l[i], _b[i], 2); + l = RLC_MAX(l, _l[i]); } - l = RLC_MAX(bn_bits(_b[0]), bn_bits(_b[1])); - l = RLC_MAX(l, RLC_MAX(bn_bits(_b[2]), bn_bits(_b[3]))); fp12_set_dig(c, 1); for (i = l - 1; i >= 0; i--) { fp12_sqr_cyc(c, c); for (j = 0; j < 4; j++) { - if (bn_get_bit(_b[j], i)) { + if (naf[j][i] > 0) { + fp12_mul(c, c, t[j]); + } + if (naf[j][i] < 0) { + fp12_inv_cyc(t[j], t[j]); fp12_mul(c, c, t[j]); + fp12_inv_cyc(t[j], t[j]); } } } @@ -647,6 +534,8 @@ void fp12_exp_cyc(fp12_t c, fp12_t a, bn_t b) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(n); + bn_free(u); for (i = 0; i < 4; i++) { bn_free(_b[i]); fp12_free(t[i]); @@ -761,13 +650,6 @@ void fp2_exp_cyc_sim(fp2_t e, fp2_t a, bn_t b, fp2_t c, bn_t d) { bn_rec_naf(naf1, &l1, d, FP_WIDTH); l = RLC_MAX(l0, l1); - for (i = l0; i < l; i++) { - naf0[i] = 0; - } - for (i = l1; i < l; i++) { - naf1[i] = 0; - } - if (bn_sign(b) == RLC_NEG) { for (i = 0; i < l0; i++) { naf0[i] = -naf0[i]; @@ -823,20 +705,23 @@ void fp2_exp_cyc_sim(fp2_t e, fp2_t a, bn_t b, fp2_t c, bn_t d) { void fp12_exp_cyc_sim(fp12_t e, fp12_t a, bn_t b, fp12_t c, bn_t d) { int i, j, l; - bn_t _b[4], _d[4]; + bn_t _b[4], _d[4], n, x; fp12_t t[4], u[4]; if (bn_is_zero(b)) { return fp12_exp_cyc(e, c, d); - return; } if (bn_is_zero(d)) { return fp12_exp_cyc(e, a, b); - return; } + bn_null(n); + bn_null(x); + RLC_TRY { + bn_new(n); + bn_new(x); for (i = 0; i < 4; i++) { bn_null(_b[i]); bn_null(_d[i]); @@ -848,8 +733,10 @@ void fp12_exp_cyc_sim(fp12_t e, fp12_t a, bn_t b, fp12_t c, bn_t d) { fp12_new(u[i]); } - fp12_glv(_b, b); - fp12_glv(_d, d); + ep_curve_get_ord(n); + fp_prime_get_par(x); + bn_rec_frb(_b, 4, b, x, n, ep_curve_is_pairf() == EP_B12); + bn_rec_frb(_d, 4, d, x, n, ep_curve_is_pairf() == EP_B12); if (ep_curve_is_pairf()) { for (i = 0; i < 4; i++) { @@ -907,6 +794,8 @@ void fp12_exp_cyc_sim(fp12_t e, fp12_t a, bn_t b, fp12_t c, bn_t d) { } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(n); + bn_free(x); for (i = 0; i < 4; i++) { bn_free(_b[i]); bn_free(_d[i]); @@ -916,12 +805,12 @@ void fp12_exp_cyc_sim(fp12_t e, fp12_t a, bn_t b, fp12_t c, bn_t d) { } } - void fp12_exp_cyc_sps(fp12_t c, fp12_t a, const int *b, int len, int sign) { int i, j, k, w = len; fp12_t t, *u = RLC_ALLOCA(fp12_t, w); if (len == 0) { + RLC_FREE(u); fp12_set_dig(c, 1); return; } @@ -995,6 +884,534 @@ void fp12_exp_cyc_sps(fp12_t c, fp12_t a, const int *b, int len, int sign) { } } +void fp24_conv_cyc(fp24_t c, fp24_t a) { + fp24_t t; + + fp24_null(t); + + RLC_TRY { + fp24_new(t); + + /* First, compute c = a^(p^12 - 1). */ + /* t = a^{-1}. */ + fp24_inv(t, a); + /* c = a^(p^12). */ + fp24_inv_cyc(c, a); + /* c = a^(p^12 - 1). */ + fp24_mul(c, c, t); + + /* Second, compute c^(p^4 + 1). */ + /* t = c^(p^4). */ + fp24_frb(t, c, 4); + + /* c = c^(p^4 + 1). */ + fp24_mul(c, c, t); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp24_free(t); + } +} + +int fp24_test_cyc(fp24_t a) { + fp24_t t0, t1; + int result = 0; + + fp24_null(t0); + fp24_null(t1); + + RLC_TRY { + fp24_new(t0); + fp24_new(t1); + + /* Check if a^(p^8 - p^4 + 1) == 1. */ + fp24_frb(t0, a, 8); + fp24_mul(t0, t0, a); + fp24_frb(t1, a, 4); + + result = ((fp24_cmp(t0, t1) == RLC_EQ) ? 1 : 0); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp24_free(t0); + fp24_free(t1); + } + + return result; +} + +void fp24_back_cyc(fp24_t c, fp24_t a) { + fp4_t t0, t1, t2; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + + /* t0 = g4^2. */ + fp4_sqr(t0, a[2][0]); + /* t1 = 3 * g4^2 - 2 * g3. */ + fp4_sub(t1, t0, a[1][1]); + fp4_dbl(t1, t1); + fp4_add(t1, t1, t0); + /* t0 = E * g5^2 + t1. */ + fp4_sqr(t2, a[2][1]); + fp4_mul_art(t0, t2); + fp4_add(t0, t0, t1); + /* t1 = 1/(4 * g2). */ + fp4_dbl(t1, a[1][0]); + fp4_dbl(t1, t1); + fp4_inv(t1, t1); + /* c_1 = g1. */ + fp4_mul(c[0][1], t0, t1); + + /* t1 = g3 * g4. */ + fp4_mul(t1, a[1][1], a[2][0]); + /* t2 = 2 * g1^2 - 3 * g3 * g4. */ + fp4_sqr(t2, c[0][1]); + fp4_sub(t2, t2, t1); + fp4_dbl(t2, t2); + fp4_sub(t2, t2, t1); + /* t1 = g2 * g5. */ + fp4_mul(t1, a[1][0], a[2][1]); + /* c_0 = E * (2 * g1^2 + g2 * g5 - 3 * g3 * g4) + 1. */ + fp4_add(t2, t2, t1); + fp4_mul_art(c[0][0], t2); + fp_add_dig(c[0][0][0][0], c[0][0][0][0], 1); + + fp4_copy(c[1][0], a[1][0]); + fp4_copy(c[1][1], a[1][1]); + fp4_copy(c[2][0], a[2][0]); + fp4_copy(c[2][1], a[2][1]); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + } +} + +void fp24_back_cyc_sim(fp24_t c[], fp24_t a[], int n) { + fp4_t *t = RLC_ALLOCA(fp4_t, n * 3); + fp4_t + *t0 = t + 0 * n, + *t1 = t + 1 * n, + *t2 = t + 2 * n; + + if (n == 0) { + RLC_FREE(t); + return; + } + + RLC_TRY { + if (t == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (int i = 0; i < n; i++) { + fp4_null(t0[i]); + fp4_null(t1[i]); + fp4_null(t2[i]); + fp4_new(t0[i]); + fp4_new(t1[i]); + fp4_new(t2[i]); + } + + for (int i = 0; i < n; i++) { + /* t0 = g4^2. */ + fp4_sqr(t0[i], a[i][2][0]); + /* t1 = 3 * g4^2 - 2 * g3. */ + fp4_sub(t1[i], t0[i], a[i][1][1]); + fp4_dbl(t1[i], t1[i]); + fp4_add(t1[i], t1[i], t0[i]); + /* t0 = E * g5^2 + t1. */ + fp4_sqr(t2[i], a[i][2][1]); + fp4_mul_art(t0[i], t2[i]); + fp4_add(t0[i], t0[i], t1[i]); + /* t1 = (4 * g2). */ + fp4_dbl(t1[i], a[i][1][0]); + fp4_dbl(t1[i], t1[i]); + } + + /* t1 = 1 / t1. */ + fp4_inv_sim(t1, t1, n); + + for (int i = 0; i < n; i++) { + /* t0 = g1. */ + fp4_mul(c[i][0][1], t0[i], t1[i]); + + /* t1 = g3 * g4. */ + fp4_mul(t1[i], a[i][1][1], a[i][2][0]); + /* t2 = 2 * g1^2 - 3 * g3 * g4. */ + fp4_sqr(t2[i], c[i][0][1]); + fp4_sub(t2[i], t2[i], t1[i]); + fp4_dbl(t2[i], t2[i]); + fp4_sub(t2[i], t2[i], t1[i]); + /* t1 = g2 * g5. */ + fp4_mul(t1[i], a[i][1][0], a[i][2][1]); + /* t2 = E * (2 * g1^2 + g2 * g5 - 3 * g3 * g4) + 1. */ + fp4_add(t2[i], t2[i], t1[i]); + fp4_mul_art(c[i][0][0], t2[i]); + fp_add_dig(c[i][0][0][0][0], c[i][0][0][0][0], 1); + + fp4_copy(c[i][1][0], a[i][1][0]); + fp4_copy(c[i][1][1], a[i][1][1]); + fp4_copy(c[i][2][0], a[i][2][0]); + fp4_copy(c[i][2][1], a[i][2][1]); + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + for (int i = 0; i < n; i++) { + fp4_free(t0[i]); + fp4_free(t1[i]); + fp4_free(t2[i]); + } + RLC_FREE(t); + } +} + +void fp24_exp_cyc(fp24_t c, fp24_t a, bn_t b) { + int i, j, k, w = bn_ham(b); + + if (bn_is_zero(b)) { + fp24_set_dig(c, 1); + return; + } + + if ((bn_bits(b) > RLC_DIG) && ((w << 3) > bn_bits(b))) { + int l, _l[8]; + int8_t naf[8][RLC_FP_BITS + 1]; + fp24_t t[8]; + bn_t _b[8], n, x; + + bn_null(n); + bn_null(x); + + RLC_TRY { + bn_new(n); + bn_new(x); + for (i = 0; i < 8; i++) { + bn_null(_b[i]); + bn_new(_b[i]); + fp24_null(t[i]); + fp24_new(t[i]); + } + + ep_curve_get_ord(n); + fp_prime_get_par(x); + bn_rec_frb(_b, 8, b, x, n, ep_curve_is_pairf()); + + if (ep_curve_is_pairf()) { + l = 0; + + fp24_copy(t[0], a); + for (i = 0; i < 8; i++) { + _l[i] = RLC_FP_BITS + 1; + bn_rec_naf(naf[i], &_l[i], _b[i], 2); + l = RLC_MAX(l, _l[i]); + if (i > 0) { + fp24_frb(t[i], t[i - 1], 1); + } + } + + for (i = 0; i < 8; i++) { + if (bn_sign(_b[i]) == RLC_NEG) { + fp24_inv_cyc(t[i], t[i]); + } + } + + fp24_set_dig(c, 1); + for (i = l - 1; i >= 0; i--) { + fp24_sqr_cyc(c, c); + for (j = 0; j < 8; j++) { + if (naf[j][i] > 0) { + fp24_mul(c, c, t[j]); + } + if (naf[j][i] < 0) { + fp24_inv_cyc(t[j], t[j]); + fp24_mul(c, c, t[j]); + fp24_inv_cyc(t[j], t[j]); + } + } + } + } else { + fp24_copy(t[0], a); + + for (i = bn_bits(b) - 2; i >= 0; i--) { + fp24_sqr_cyc(t[0], t[0]); + if (bn_get_bit(b, i)) { + fp24_mul(t[0], t[0], a); + } + } + + fp24_copy(c, t[0]); + if (bn_sign(b) == RLC_NEG) { + fp24_inv_cyc(c, c); + } + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(x); + for (i = 0; i < 8; i++) { + bn_free(_b[i]); + fp24_free(t[i]); + } + } + } else { + fp24_t t, *u = RLC_ALLOCA(fp24_t, w); + + fp24_null(t); + + RLC_TRY { + if (u == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < w; i++) { + fp24_null(u[i]); + fp24_new(u[i]); + } + fp24_new(t); + + j = 0; + fp24_copy(t, a); + for (i = 1; i < bn_bits(b); i++) { + fp24_sqr_pck(t, t); + if (bn_get_bit(b, i)) { + fp24_copy(u[j++], t); + } + } + + if (!bn_is_even(b)) { + j = 0; + k = w - 1; + } else { + j = 1; + k = w; + } + + fp24_back_cyc_sim(u, u, k); + + if (!bn_is_even(b)) { + fp24_copy(c, a); + } else { + fp24_copy(c, u[0]); + } + + for (i = j; i < k; i++) { + fp24_mul(c, c, u[i]); + } + + if (bn_sign(b) == RLC_NEG) { + fp24_inv_cyc(c, c); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < w; i++) { + fp24_free(u[i]); + } + fp24_free(t); + RLC_FREE(u); + } + } +} + +void fp24_exp_cyc_sim(fp24_t e, fp24_t a, bn_t b, fp24_t c, bn_t d) { + int i, l, n0, n1, l0, l1; + int8_t naf0[RLC_FP_BITS + 1], naf1[RLC_FP_BITS + 1], *_k, *_m; + fp24_t r, t0[1 << (EP_WIDTH - 2)]; + fp24_t s, t1[1 << (EP_WIDTH - 2)]; + + if (bn_is_zero(b)) { + return fp24_exp_cyc(e, c, d); + } + + if (bn_is_zero(d)) { + return fp24_exp_cyc(e, a, b); + } + + fp24_null(r); + fp24_null(s); + + RLC_TRY { + fp24_new(r); + fp24_new(s); + for (i = 0; i < (1 << (FP_WIDTH - 2)); i ++) { + fp24_null(t0[i]); + fp24_null(t1[i]); + fp24_new(t0[i]); + fp24_new(t1[i]); + } + +#if FP_WIDTH > 2 + fp24_sqr(t0[0], a); + fp24_mul(t0[1], t0[0], a); + for (int i = 2; i < (1 << (FP_WIDTH - 2)); i++) { + fp24_mul(t0[i], t0[i - 1], t0[0]); + } + + fp24_sqr(t1[0], c); + fp24_mul(t1[1], t1[0], c); + for (int i = 2; i < (1 << (FP_WIDTH - 2)); i++) { + fp24_mul(t1[i], t1[i - 1], t1[0]); + } +#endif + fp24_copy(t0[0], a); + fp24_copy(t1[0], c); + + l0 = l1 = RLC_FP_BITS + 1; + bn_rec_naf(naf0, &l0, b, FP_WIDTH); + bn_rec_naf(naf1, &l1, d, FP_WIDTH); + + l = RLC_MAX(l0, l1); + if (bn_sign(b) == RLC_NEG) { + for (i = 0; i < l0; i++) { + naf0[i] = -naf0[i]; + } + } + if (bn_sign(d) == RLC_NEG) { + for (i = 0; i < l1; i++) { + naf1[i] = -naf1[i]; + } + } + + _k = naf0 + l - 1; + _m = naf1 + l - 1; + + fp24_set_dig(r, 1); + for (i = l - 1; i >= 0; i--, _k--, _m--) { + fp24_sqr(r, r); + + n0 = *_k; + n1 = *_m; + + if (n0 > 0) { + fp24_mul(r, r, t0[n0 / 2]); + } + if (n0 < 0) { + fp24_inv_cyc(s, t0[-n0 / 2]); + fp24_mul(r, r, s); + } + if (n1 > 0) { + fp24_mul(r, r, t1[n1 / 2]); + } + if (n1 < 0) { + fp24_inv_cyc(s, t1[-n1 / 2]); + fp24_mul(r, r, s); + } + } + + fp24_copy(e, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp24_free(r); + fp24_free(s); + for (i = 0; i < (1 << (FP_WIDTH - 2)); i++) { + fp24_free(t0[i]); + fp24_free(t1[i]); + } + } +} + +void fp24_exp_cyc_sps(fp24_t c, fp24_t a, const int *b, int len, int sign) { + int i, j, k, w = len; + fp24_t t, *u = RLC_ALLOCA(fp24_t, w); + + if (len == 0) { + RLC_FREE(u); + fp24_set_dig(c, 1); + return; + } + + fp24_null(t); + + RLC_TRY { + if (u == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < w; i++) { + fp24_null(u[i]); + fp24_new(u[i]); + } + fp24_new(t); + + fp24_copy(t, a); + if (b[0] == 0) { + for (j = 0, i = 1; i < len; i++) { + k = (b[i] < 0 ? -b[i] : b[i]); + for (; j < k; j++) { + fp24_sqr_pck(t, t); + } + if (b[i] < 0) { + fp24_inv_cyc(u[i - 1], t); + } else { + fp24_copy(u[i - 1], t); + } + } + + fp24_back_cyc_sim(u, u, w - 1); + + fp24_copy(c, a); + for (i = 0; i < w - 1; i++) { + fp24_mul(c, c, u[i]); + } + } else { + for (j = 0, i = 0; i < len; i++) { + k = (b[i] < 0 ? -b[i] : b[i]); + for (; j < k; j++) { + fp24_sqr_pck(t, t); + } + if (b[i] < 0) { + fp24_inv_cyc(u[i], t); + } else { + fp24_copy(u[i], t); + } + } + + fp24_back_cyc_sim(u, u, w); + + fp24_copy(c, u[0]); + for (i = 1; i < w; i++) { + fp24_mul(c, c, u[i]); + } + } + + if (sign == RLC_NEG) { + fp24_inv_cyc(c, c); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < w; i++) { + fp24_free(u[i]); + } + fp24_free(t); + RLC_FREE(u); + } +} + void fp48_conv_cyc(fp48_t c, fp48_t a) { fp48_t t; @@ -1121,6 +1538,7 @@ void fp48_back_cyc_sim(fp48_t c[], fp48_t a[], int n) { *t2 = t + 2 * n; if (n == 0) { + RLC_FREE(t); return; } @@ -1195,8 +1613,7 @@ void fp48_exp_cyc(fp48_t c, fp48_t a, bn_t b) { int i, j, k, w = bn_ham(b); if (bn_is_zero(b)) { - fp48_set_dig(c, 1); - return; + return fp48_set_dig(c, 1); } if ((bn_bits(b) > RLC_DIG) && ((w << 3) > bn_bits(b))) { @@ -1292,6 +1709,7 @@ void fp48_exp_cyc_sps(fp48_t c, fp48_t a, const int *b, int len, int sign) { fp48_t t, *u = RLC_ALLOCA(fp48_t, w); if (len == 0) { + RLC_FREE(u); fp48_set_dig(c, 1); return; } @@ -1490,6 +1908,7 @@ void fp54_back_cyc_sim(fp54_t c[], fp54_t a[], int n) { *t2 = t + 2 * n; if (n == 0) { + RLC_FREE(t); return; } @@ -1564,8 +1983,7 @@ void fp54_exp_cyc(fp54_t c, fp54_t a, bn_t b) { int i, j, k, w = bn_ham(b); if (bn_is_zero(b)) { - fp54_set_dig(c, 1); - return; + return fp54_set_dig(c, 1); } if ((bn_bits(b) > RLC_DIG) && ((w << 3) > bn_bits(b))) { @@ -1662,6 +2080,7 @@ void fp54_exp_cyc_sps(fp54_t c, fp54_t a, const int *b, int len, int sign) { fp54_t t, *u = RLC_ALLOCA(fp54_t, w); if (len == 0) { + RLC_FREE(u); fp54_set_dig(c, 1); return; } diff --git a/contrib/relic/src/fpx/relic_fpx_exp.c b/contrib/relic/src/fpx/relic_fpx_exp.c index b6341feaf..e559e7ffe 100644 --- a/contrib/relic/src/fpx/relic_fpx_exp.c +++ b/contrib/relic/src/fpx/relic_fpx_exp.c @@ -326,25 +326,42 @@ void fp12_exp(fp12_t c, fp12_t a, bn_t b) { } void fp12_exp_dig(fp12_t c, fp12_t a, dig_t b) { - fp12_t t; + bn_t _b; + fp12_t t, v; + int8_t u, naf[RLC_DIG + 1]; + int l; if (b == 0) { fp12_set_dig(c, 1); return; } + bn_null(_b); fp12_null(t); + fp12_null(v); RLC_TRY { + bn_new(_b); fp12_new(t); + fp12_new(v); fp12_copy(t, a); if (fp12_test_cyc(a)) { - for (int i = util_bits_dig(b) - 2; i >= 0; i--) { + fp12_inv_cyc(v, a); + bn_set_dig(_b, b); + + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _b, 2); + + for (int i = bn_bits(_b) - 2; i >= 0; i--) { fp12_sqr_cyc(t, t); - if (b & ((dig_t)1 << i)) { + + u = naf[i]; + if (u > 0) { fp12_mul(t, t, a); + } else if (u < 0) { + fp12_mul(t, t, v); } } } else { @@ -362,7 +379,9 @@ void fp12_exp_dig(fp12_t c, fp12_t a, dig_t b) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(_b); fp12_free(t); + fp12_free(v); } } @@ -438,6 +457,66 @@ void fp24_exp(fp24_t c, fp24_t a, bn_t b) { } } +void fp24_exp_dig(fp24_t c, fp24_t a, dig_t b) { + bn_t _b; + fp24_t t, v; + int8_t u, naf[RLC_DIG + 1]; + int l; + + if (b == 0) { + fp24_set_dig(c, 1); + return; + } + + bn_null(_b); + fp24_null(t); + fp24_null(v); + + RLC_TRY { + bn_new(_b); + fp24_new(t); + fp24_new(v); + + fp24_copy(t, a); + + if (fp24_test_cyc(a)) { + fp24_inv_cyc(v, a); + bn_set_dig(_b, b); + + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _b, 2); + + for (int i = bn_bits(_b) - 2; i >= 0; i--) { + fp24_sqr_cyc(t, t); + + u = naf[i]; + if (u > 0) { + fp24_mul(t, t, a); + } else if (u < 0) { + fp24_mul(t, t, v); + } + } + } else { + for (int i = util_bits_dig(b) - 2; i >= 0; i--) { + fp24_sqr(t, t); + if (b & ((dig_t)1 << i)) { + fp24_mul(t, t, a); + } + } + } + + fp24_copy(c, t); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(_b); + fp24_free(t); + fp24_free(v); + } +} + void fp48_exp(fp48_t c, fp48_t a, bn_t b) { fp48_t t; @@ -479,25 +558,42 @@ void fp48_exp(fp48_t c, fp48_t a, bn_t b) { } void fp48_exp_dig(fp48_t c, fp48_t a, dig_t b) { - fp48_t t; + bn_t _b; + fp48_t t, v; + int8_t u, naf[RLC_DIG + 1]; + int l; if (b == 0) { fp48_set_dig(c, 1); return; } + bn_null(_b); fp48_null(t); + fp48_null(v); RLC_TRY { + bn_new(_b); fp48_new(t); + fp48_new(v); fp48_copy(t, a); if (fp48_test_cyc(a)) { - for (int i = util_bits_dig(b) - 2; i >= 0; i--) { + fp48_inv_cyc(v, a); + bn_set_dig(_b, b); + + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _b, 2); + + for (int i = bn_bits(_b) - 2; i >= 0; i--) { fp48_sqr_cyc(t, t); - if (b & ((dig_t)1 << i)) { + + u = naf[i]; + if (u > 0) { fp48_mul(t, t, a); + } else if (u < 0) { + fp48_mul(t, t, v); } } } else { @@ -515,7 +611,9 @@ void fp48_exp_dig(fp48_t c, fp48_t a, dig_t b) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(_b); fp48_free(t); + fp48_free(v); } } @@ -556,25 +654,42 @@ void fp54_exp(fp54_t c, fp54_t a, bn_t b) { } void fp54_exp_dig(fp54_t c, fp54_t a, dig_t b) { - fp54_t t; + bn_t _b; + fp54_t t, v; + int8_t u, naf[RLC_DIG + 1]; + int l; if (b == 0) { fp54_set_dig(c, 1); return; } + bn_null(_b); fp54_null(t); + fp54_null(v); RLC_TRY { + bn_new(_b); fp54_new(t); + fp54_new(v); fp54_copy(t, a); if (fp54_test_cyc(a)) { - for (int i = util_bits_dig(b) - 2; i >= 0; i--) { + fp54_inv_cyc(v, a); + bn_set_dig(_b, b); + + l = RLC_DIG + 1; + bn_rec_naf(naf, &l, _b, 2); + + for (int i = bn_bits(_b) - 2; i >= 0; i--) { fp54_sqr_cyc(t, t); - if (b & ((dig_t)1 << i)) { + + u = naf[i]; + if (u > 0) { fp54_mul(t, t, a); + } else if (u < 0) { + fp54_mul(t, t, v); } } } else { @@ -592,6 +707,8 @@ void fp54_exp_dig(fp54_t c, fp54_t a, dig_t b) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + bn_free(_b); fp54_free(t); + fp54_free(v); } } diff --git a/contrib/relic/src/fpx/relic_fpx_field.c b/contrib/relic/src/fpx/relic_fpx_field.c index 7799fe4c9..92d9557e3 100644 --- a/contrib/relic/src/fpx/relic_fpx_field.c +++ b/contrib/relic/src/fpx/relic_fpx_field.c @@ -222,3 +222,32 @@ void fp3_field_init(void) { fp3_free(t2); } } + +void fp4_field_init() { + bn_t e; + fp4_t t0; + ctx_t *ctx = core_get(); + + bn_null(e); + fp4_null(t0); + + RLC_TRY { + bn_new(e); + fp4_new(t0); + + fp4_set_dig(t0, 1); + fp4_mul_art(t0, t0); + e->used = RLC_FP_DIGS; + dv_copy(e->dp, fp_prime_get(), RLC_FP_DIGS); + bn_sub_dig(e, e, 1); + bn_div_dig(e, e, 6); + fp4_exp(t0, t0, e); + fp_copy(ctx->fp4_p1[0], t0[1][0]); + fp_copy(ctx->fp4_p1[1], t0[1][1]); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(e); + fp4_free(t0); + } +} diff --git a/contrib/relic/src/fpx/relic_fpx_inv.c b/contrib/relic/src/fpx/relic_fpx_inv.c index e4fa3355b..b279f879c 100644 --- a/contrib/relic/src/fpx/relic_fpx_inv.c +++ b/contrib/relic/src/fpx/relic_fpx_inv.c @@ -296,6 +296,49 @@ void fp4_inv(fp4_t c, fp4_t a) { } } +void fp4_inv_sim(fp4_t * c, fp4_t * a, int n) { + int i; + fp4_t u, *t = RLC_ALLOCA(fp4_t, n); + + for (i = 0; i < n; i++) { + fp4_null(t[i]); + } + fp4_null(u); + + RLC_TRY { + for (i = 0; i < n; i++) { + fp4_new(t[i]); + } + fp4_new(u); + + fp4_copy(c[0], a[0]); + fp4_copy(t[0], a[0]); + + for (i = 1; i < n; i++) { + fp4_copy(t[i], a[i]); + fp4_mul(c[i], c[i - 1], t[i]); + } + + fp4_inv(u, c[n - 1]); + + for (i = n - 1; i > 0; i--) { + fp4_mul(c[i], c[i - 1], u); + fp4_mul(u, u, t[i]); + } + fp4_copy(c[0], u); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + for (i = 0; i < n; i++) { + fp4_free(t[i]); + } + fp4_free(u); + RLC_FREE(t); + } +} + void fp6_inv(fp6_t c, fp6_t a) { fp2_t v0; fp2_t v1; @@ -658,6 +701,13 @@ void fp24_inv(fp24_t c, fp24_t a) { } } +void fp24_inv_cyc(fp24_t c, fp24_t a) { + fp8_inv_cyc(c[0], a[0]); + fp8_inv_cyc(c[1], a[1]); + fp8_neg(c[1], c[1]); + fp8_inv_cyc(c[2], a[2]); +} + void fp48_inv(fp48_t c, fp48_t a) { fp24_t t0; fp24_t t1; diff --git a/contrib/relic/src/fpx/relic_fpx_pck.c b/contrib/relic/src/fpx/relic_fpx_pck.c index ce09f829f..1f9b6b9f9 100644 --- a/contrib/relic/src/fpx/relic_fpx_pck.c +++ b/contrib/relic/src/fpx/relic_fpx_pck.c @@ -155,6 +155,28 @@ int fp12_upk_max(fp12_t c, fp12_t a) { } } +void fp24_pck(fp24_t c, fp24_t a) { + fp24_copy(c, a); + if (fp24_test_cyc(c)) { + fp4_zero(c[0][0]); + fp4_zero(c[0][1]); + } +} + +int fp24_upk(fp24_t c, fp24_t a) { + if (fp4_is_zero(a[0][0]) && fp4_is_zero(a[0][1])) { + fp24_back_cyc(c, a); + if (fp24_test_cyc(c)) { + return 1; + } else { + return 0; + } + } else { + fp24_copy(c, a); + return 1; + } +} + void fp48_pck(fp48_t c, fp48_t a) { fp48_copy(c, a); if (fp48_test_cyc(c)) { diff --git a/contrib/relic/src/fpx/relic_fpx_srt.c b/contrib/relic/src/fpx/relic_fpx_srt.c index 3e7fdb530..2da52b750 100644 --- a/contrib/relic/src/fpx/relic_fpx_srt.c +++ b/contrib/relic/src/fpx/relic_fpx_srt.c @@ -38,72 +38,80 @@ int fp2_srt(fp2_t c, fp2_t a) { int r = 0; + fp_t t0; fp_t t1; fp_t t2; - fp_t t3; + fp_null(t0); fp_null(t1); fp_null(t2); - fp_null(t3); + + if (fp2_is_zero(a)) { + fp2_zero(c); + return 1; + } RLC_TRY { + fp_new(t0); fp_new(t1); fp_new(t2); - fp_new(t3); if (fp_is_zero(a[1])) { /* special case: either a[0] is square and sqrt is purely 'real' * or a[0] is non-square and sqrt is purely 'imaginary' */ r = 1; - if (fp_srt(t1, a[0])) { - fp_copy(c[0], t1); + if (fp_srt(t0, a[0])) { + fp_copy(c[0], t0); fp_zero(c[1]); } else { - /* Compute a[0]/u^2. */ + /* Compute a[0]/i^2. */ #ifdef FP_QNRES - fp_copy(t1, a[0]); + fp_copy(t0, a[0]); #else if (fp_prime_get_qnr() == -2) { - fp_hlv(t1, a[0]); + fp_hlv(t0, a[0]); } else { - fp_set_dig(t1, -fp_prime_get_qnr()); - fp_inv(t1, t1); - fp_mul(t1, t1, a[0]); + fp_set_dig(t0, -fp_prime_get_qnr()); + fp_inv(t0, t0); + fp_mul(t0, t0, a[0]); } #endif - fp_neg(t1, t1); + fp_neg(t0, t0); fp_zero(c[0]); - if (!fp_srt(c[1], t1)) { + if (!fp_srt(c[1], t0)) { /* should never happen! */ RLC_THROW(ERR_NO_VALID); } } } else { - /* t1 = a[0]^2 - u^2 * a[1]^2 */ - fp_sqr(t1, a[0]); - fp_sqr(t2, a[1]); + /* t0 = a[0]^2 - i^2 * a[1]^2 */ + fp_sqr(t0, a[0]); + fp_sqr(t1, a[1]); for (int i = -1; i > fp_prime_get_qnr(); i--) { - fp_add(t1, t1, t2); + fp_add(t0, t0, t1); } - fp_add(t1, t1, t2); - - if (fp_srt(t2, t1)) { - /* t1 = (a_0 + sqrt(t1)) / 2 */ - fp_add(t1, a[0], t2); - fp_hlv(t1, t1); - - if (!fp_srt(t3, t1)) { - /* t1 = (a_0 - sqrt(t1)) / 2 */ - fp_sub(t1, a[0], t2); - fp_hlv(t1, t1); - fp_srt(t3, t1); + fp_add(t0, t0, t1); + + if (fp_srt(t1, t0)) { + /* t0 = (a_0 + sqrt(t0)) / 2 */ + fp_add(t0, a[0], t1); + fp_hlv(t0, t0); + + if (!fp_srt(t2, t0)) { + /* t0 = (a_0 - sqrt(t0)) / 2 */ + fp_sub(t0, a[0], t1); + fp_hlv(t0, t0); + if (!fp_srt(t2, t0)) { + /* should never happen! */ + RLC_THROW(ERR_NO_VALID); + } } - /* c_0 = sqrt(t1) */ - fp_copy(c[0], t3); - /* c_1 = a_1 / (2 * sqrt(t1)) */ - fp_dbl(t3, t3); - fp_inv(t3, t3); - fp_mul(c[1], a[1], t3); + /* c_0 = sqrt(t0) */ + fp_copy(c[0], t2); + /* c_1 = a_1 / (2 * sqrt(t0)) */ + fp_dbl(t2, t2); + fp_inv(t2, t2); + fp_mul(c[1], a[1], t2); r = 1; } } @@ -112,9 +120,9 @@ int fp2_srt(fp2_t c, fp2_t a) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { + fp_free(t0); fp_free(t1); fp_free(t2); - fp_free(t3); } return r; } @@ -130,6 +138,11 @@ int fp3_srt(fp3_t c, fp3_t a) { fp3_null(t3); bn_null(e); + if (fp3_is_zero(a)) { + fp3_zero(c); + return 1; + } + RLC_TRY { fp3_new(t0); fp3_new(t1); @@ -202,3 +215,85 @@ int fp3_srt(fp3_t c, fp3_t a) { return r; } + +int fp4_srt(fp4_t c, fp4_t a) { + int r = 0; + fp2_t t0, t1, t2; + + fp2_null(t0); + fp2_null(t1); + fp2_null(t2); + + if (fp4_is_zero(a)) { + fp4_zero(c); + return 1; + } + + RLC_TRY { + fp2_new(t0); + fp2_new(t1); + fp2_new(t2); + + if (fp2_is_zero(a[1])) { + /* special case: either a[0] is square and sqrt is purely 'real' + * or a[0] is non-square and sqrt is purely 'imaginary' */ + r = 1; + if (fp2_srt(t0, a[0])) { + fp2_copy(c[0], t0); + fp2_zero(c[1]); + } else { + /* Compute a[0]/s^2. */ + fp2_set_dig(t0, 1); + fp2_mul_nor(t0, t0); + fp2_inv(t0, t0); + fp2_mul(t0, a[0], t0); + fp2_neg(t0, t0); + fp2_zero(c[0]); + if (!fp2_srt(c[1], t0)) { + /* should never happen! */ + RLC_THROW(ERR_NO_VALID); + } + fp2_mul_art(c[1], c[1]); + } + } else { + /* t0 = a[0]^2 - s^2 * a[1]^2 */ + fp2_sqr(t0, a[0]); + fp2_sqr(t1, a[1]); + fp2_mul_nor(t2, t1); + fp2_sub(t0, t0, t2); + + if (fp2_srt(t1, t0)) { + /* t0 = (a_0 + sqrt(t0)) / 2 */ + fp2_add(t0, a[0], t1); + fp_hlv(t0[0], t0[0]); + fp_hlv(t0[1], t0[1]); + + if (!fp2_srt(t2, t0)) { + /* t0 = (a_0 - sqrt(t0)) / 2 */ + fp2_sub(t0, a[0], t1); + fp_hlv(t0[0], t0[0]); + fp_hlv(t0[1], t0[1]); + if (!fp2_srt(t2, t0)) { + /* should never happen! */ + RLC_THROW(ERR_NO_VALID); + } + } + /* c_0 = sqrt(t0) */ + fp2_copy(c[0], t2); + + /* c_1 = a_1 / (2 * sqrt(t0)) */ + fp2_dbl(t2, t2); + fp2_inv(t2, t2); + fp2_mul(c[1], a[1], t2); + r = 1; + } + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp2_free(t0); + fp2_free(t1); + fp2_free(t2); + } + return r; +} diff --git a/contrib/relic/src/fpx/relic_fpx_util.c b/contrib/relic/src/fpx/relic_fpx_util.c index d2a69e4ad..1de8cc6fc 100644 --- a/contrib/relic/src/fpx/relic_fpx_util.c +++ b/contrib/relic/src/fpx/relic_fpx_util.c @@ -583,28 +583,69 @@ void fp24_print(fp24_t a) { fp8_print(a[2]); } -int fp24_size_bin(fp24_t a) { - return 24 * RLC_FP_BYTES; +int fp24_size_bin(fp24_t a, int pack) { + if (pack) { + if (fp24_test_cyc(a)) { + return 16 * RLC_FP_BYTES; + } else { + return 24 * RLC_FP_BYTES; + } + } else { + return 24 * RLC_FP_BYTES; + } } void fp24_read_bin(fp24_t a, const uint8_t *bin, int len) { - if (len != 24 * RLC_FP_BYTES) { + if (len != 16 * RLC_FP_BYTES && len != 24 * RLC_FP_BYTES) { RLC_THROW(ERR_NO_BUFFER); return; } - fp8_read_bin(a[0], bin, 8 * RLC_FP_BYTES); - fp8_read_bin(a[1], bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES); - fp8_read_bin(a[2], bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES); + if (len == 16 * RLC_FP_BYTES) { + fp4_zero(a[0][0]); + fp4_zero(a[0][1]); + fp4_read_bin(a[1][0], bin, 4 * RLC_FP_BYTES); + fp4_read_bin(a[1][1], bin + 4 * RLC_FP_BYTES, 4 * RLC_FP_BYTES); + fp4_read_bin(a[2][0], bin + 8 * RLC_FP_BYTES, 4 * RLC_FP_BYTES); + fp4_read_bin(a[2][1], bin + 12 * RLC_FP_BYTES, 4 * RLC_FP_BYTES); + fp24_back_cyc(a, a); + } + if (len == 24 * RLC_FP_BYTES) { + fp8_read_bin(a[0], bin, 8 * RLC_FP_BYTES); + fp8_read_bin(a[1], bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES); + fp8_read_bin(a[2], bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES); + } } -void fp24_write_bin(uint8_t *bin, int len, fp24_t a) { - if (len != 24 * RLC_FP_BYTES) { - RLC_THROW(ERR_NO_BUFFER); - return; +void fp24_write_bin(uint8_t *bin, int len, fp24_t a, int pack) { + fp24_t t; + + fp24_null(t); + + RLC_TRY { + fp24_new(t); + + if (pack) { + if (len != 16 * RLC_FP_BYTES) { + RLC_THROW(ERR_NO_BUFFER); + } + fp24_pck(t, a); + fp4_write_bin(bin, 4 * RLC_FP_BYTES, a[1][0]); + fp4_write_bin(bin + 4 * RLC_FP_BYTES, 4 * RLC_FP_BYTES, a[1][1]); + fp4_write_bin(bin + 8 * RLC_FP_BYTES, 4 * RLC_FP_BYTES, a[2][0]); + fp4_write_bin(bin + 12 * RLC_FP_BYTES, 4 * RLC_FP_BYTES, a[2][1]); + } else { + if (len != 24 * RLC_FP_BYTES) { + RLC_THROW(ERR_NO_BUFFER); + } + fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0]); + fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1]); + fp8_write_bin(bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[2]); + } + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp24_free(t); } - fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0]); - fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1]); - fp8_write_bin(bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[2]); } void fp24_set_dig(fp24_t a, dig_t b) { @@ -690,8 +731,8 @@ void fp48_write_bin(uint8_t *bin, int len, fp48_t a, int pack) { if (len != 48 * RLC_FP_BYTES) { RLC_THROW(ERR_NO_BUFFER); } - fp24_write_bin(bin, 24 * RLC_FP_BYTES, a[0]); - fp24_write_bin(bin + 24 * RLC_FP_BYTES, 24 * RLC_FP_BYTES, a[1]); + fp24_write_bin(bin, 24 * RLC_FP_BYTES, a[0], 0); + fp24_write_bin(bin + 24 * RLC_FP_BYTES, 24 * RLC_FP_BYTES, a[1], 0); } } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/contrib/relic/src/low/easy/relic_bn_div_low.c b/contrib/relic/src/low/easy/relic_bn_div_low.c index 69a9ec686..c03e37fa9 100644 --- a/contrib/relic/src/low/easy/relic_bn_div_low.c +++ b/contrib/relic/src/low/easy/relic_bn_div_low.c @@ -83,13 +83,9 @@ void bn_divn_low(dig_t *c, dig_t *d, dig_t *a, int sa, dig_t *b, int sb) { } if (a[i] == b[t]) { - c[i - t - 1] = ((((dbl_t)1) << RLC_DIG) - 1); + c[i - t - 1] = RLC_MASK(RLC_DIG); } else { - dbl_t tmp; - tmp = ((dbl_t)a[i]) << ((dbl_t)RLC_DIG); - tmp |= (dbl_t)(a[i - 1]); - tmp /= (dbl_t)(b[t]); - c[i - t - 1] = (dig_t)tmp; + RLC_DIV_DIG(c[i - t - 1], carry, a[i], a[i - 1], b[t]); } c[i - t - 1]++; @@ -130,21 +126,12 @@ void bn_divn_low(dig_t *c, dig_t *d, dig_t *a, int sa, dig_t *b, int sb) { } void bn_div1_low(dig_t *c, dig_t *d, const dig_t *a, int size, dig_t b) { - dbl_t w; - dig_t r; - int i; + dig_t q, r, w = 0; - w = 0; - for (i = size - 1; i >= 0; i--) { - w = (w << ((dbl_t)RLC_DIG)) | ((dbl_t)a[i]); - - if (w >= b) { - r = (dig_t)(w / b); - w -= ((dbl_t)r) * ((dbl_t)b); - } else { - r = 0; - } - c[i] = (dig_t)r; + for (int i = size - 1; i >= 0; i--) { + RLC_DIV_DIG(q, r, w, a[i], b); + c[i] = q; + w = r; } *d = (dig_t)w; } diff --git a/contrib/relic/src/low/easy/relic_bn_mod_low.c b/contrib/relic/src/low/easy/relic_bn_mod_low.c index 2be2a5f4f..304422580 100644 --- a/contrib/relic/src/low/easy/relic_bn_mod_low.c +++ b/contrib/relic/src/low/easy/relic_bn_mod_low.c @@ -32,42 +32,7 @@ #include "relic_bn.h" #include "relic_bn_low.h" - -/*============================================================================*/ -/* Private definitions */ -/*============================================================================*/ - -/** - * Accumulates a double precision digit in a triple register variable. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - * @param[in] B - the second digit to multiply. - */ -#define COMBA_STEP_BN_MOD_LOW(R2, R1, R0, A, B) \ - dbl_t r = (dbl_t)(A) * (dbl_t)(B); \ - dig_t _r = (R1); \ - (R0) += (dig_t)(r); \ - (R1) += (R0) < (dig_t)(r); \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)(r >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)(r >> (dbl_t)RLC_DIG); \ - -/** - * Accumulates a single precision digit in a triple register variable. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to accumulate. - */ -#define COMBA_ADD(R2, R1, R0, A) \ - dig_t __r = (R1); \ - (R0) += (A); \ - (R1) += (R0) < (A); \ - (R2) += (R1) < __r; \ +#include "relic_util.h" /*============================================================================*/ /* Public definitions */ @@ -75,7 +40,7 @@ void bn_modn_low(dig_t *c, const dig_t *a, int sa, const dig_t *m, int sm, dig_t u) { int i, j; - dig_t r0, r1, r2; + dig_t t, r0, r1, r2; dig_t *tmp, *tmpc; const dig_t *tmpm; @@ -86,13 +51,13 @@ void bn_modn_low(dig_t *c, const dig_t *a, int sa, const dig_t *m, int sm, dig_t tmp = c; tmpm = m + i; for (j = 0; j < i; j++, tmp++, tmpm--) { - COMBA_STEP_BN_MOD_LOW(r2, r1, r0, *tmp, *tmpm); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmp, *tmpm); } if (i < sa) { - COMBA_ADD(r2, r1, r0, *a); + RLC_COMBA_ADD(t, r2, r1, r0, *a); } *tmpc = (dig_t)(r0 * u); - COMBA_STEP_BN_MOD_LOW(r2, r1, r0, *tmpc, *m); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpc, *m); r0 = r1; r1 = r2; r2 = 0; @@ -101,10 +66,10 @@ void bn_modn_low(dig_t *c, const dig_t *a, int sa, const dig_t *m, int sm, dig_t tmp = c + (i - sm + 1); tmpm = m + sm - 1; for (j = i - sm + 1; j < sm; j++, tmp++, tmpm--) { - COMBA_STEP_BN_MOD_LOW(r2, r1, r0, *tmp, *tmpm); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmp, *tmpm); } if (i < sa) { - COMBA_ADD(r2, r1, r0, *a); + RLC_COMBA_ADD(t, r2, r1, r0, *a); } c[i - sm] = r0; r0 = r1; @@ -113,7 +78,7 @@ void bn_modn_low(dig_t *c, const dig_t *a, int sa, const dig_t *m, int sm, dig_t } if (i < sa) { - COMBA_ADD(r2, r1, r0, *a); + RLC_COMBA_ADD(t, r2, r1, r0, *a); } c[sm - 1] = r0; if (r1) { diff --git a/contrib/relic/src/low/easy/relic_bn_mul_low.c b/contrib/relic/src/low/easy/relic_bn_mul_low.c index b640a6451..0e4c67e4d 100644 --- a/contrib/relic/src/low/easy/relic_bn_mul_low.c +++ b/contrib/relic/src/low/easy/relic_bn_mul_low.c @@ -32,69 +32,65 @@ #include "relic_bn.h" #include "relic_bn_low.h" - -/*============================================================================*/ -/* Private definitions */ -/*============================================================================*/ - -/** - * Accumulates a double precision digit in a triple register variable. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - * @param[in] B - the second digit to multiply. - */ -#define COMBA_STEP_BN_MUL_LOW(R2, R1, R0, A, B) \ - dbl_t r = (dbl_t)(A) * (dbl_t)(B); \ - dig_t _r = (R1); \ - (R0) += (dig_t)(r); \ - (R1) += (R0) < (dig_t)(r); \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)((r) >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)((r) >> (dbl_t)RLC_DIG); \ +#include "relic_util.h" /*============================================================================*/ /* Public definitions */ /*============================================================================*/ dig_t bn_mula_low(dig_t *c, const dig_t *a, dig_t digit, int size) { - int i; - dig_t carry; - dbl_t r; - - carry = 0; - for (i = 0; i < size; i++, a++, c++) { - /* Multiply the digit *tmpa by b and accumulate with the previous + dig_t _c, r0, r1, carry = 0; + for (int i = 0; i < size; i++, a++, c++) { + /* Multiply the digit *a by d and accumulate with the previous * result in the same columns and the propagated carry. */ - r = (dbl_t)(*c) + (dbl_t)(*a) * (dbl_t)(digit) + (dbl_t)(carry); + RLC_MUL_DIG(r1, r0, *a, digit); + _c = r0 + carry; + carry = r1 + (_c < carry); /* Increment the column and assign the result. */ - *c = (dig_t)r; + *c = *c + _c; /* Update the carry. */ - carry = (dig_t)(r >> (dbl_t)RLC_DIG); + carry += (*c < _c); } return carry; } dig_t bn_mul1_low(dig_t *c, const dig_t *a, dig_t digit, int size) { - int i; - dig_t carry; - dbl_t r; - - carry = 0; - for (i = 0; i < size; i++, a++, c++) { - /* Multiply the digit *tmpa by b and accumulate with the previous - * result in the same columns and the propagated carry. */ - r = (dbl_t)(carry) + (dbl_t)(*a) * (dbl_t)(digit); - /* Increment the column and assign the result. */ - *c = (dig_t)r; - /* Update the carry. */ - carry = (dig_t)(r >> (dbl_t)RLC_DIG); + dig_t r0, r1, carry = 0; + for (int i = 0; i < size; i++, a++, c++) { + RLC_MUL_DIG(r1, r0, *a, digit); + *c = r0 + carry; + carry = r1 + (*c < carry); } return carry; } +dig_t bn_muls_low(dig_t *c, const dig_t *a, dig_t sa, dis_t digit, int size) { + dig_t r, _a, _c, c0, c1, c2, sign, sd = digit >> (RLC_DIG - 1); + + sa = -sa; + sign = sa ^ sd; + digit = (digit ^ sd) - sd; + + _a = (a[0] ^ sa) - sa; + c2 = (_a < (a[0] ^ sa)); + RLC_MUL_DIG(r, _c, _a, (dig_t)digit); + _c ^= sign; + c[0] = _c - sign; + c1 = (c[0] < _c); + c0 = r; + for (int i = 1; i < size; i++) { + _a = (a[i] ^ sa) + c2; + c2 = (_a < c2); + RLC_MUL_DIG(r, _c, _a, (dig_t)digit); + _c += c0; + c0 = r + (_c < c0); + _c ^= sign; + c[i] = _c + c1; + c1 = (c[i] < _c); + } + return (c0 ^ sign) + c1; +} + void bn_muln_low(dig_t *c, const dig_t *a, const dig_t *b, int size) { int i, j; const dig_t *tmpa, *tmpb; @@ -105,7 +101,7 @@ void bn_muln_low(dig_t *c, const dig_t *a, const dig_t *b, int size) { tmpa = a; tmpb = b + i; for (j = 0; j <= i; j++, tmpa++, tmpb--) { - COMBA_STEP_BN_MUL_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; @@ -116,7 +112,7 @@ void bn_muln_low(dig_t *c, const dig_t *a, const dig_t *b, int size) { tmpa = a + i + 1; tmpb = b + (size - 1); for (j = 0; j < size - (i + 1); j++, tmpa++, tmpb--) { - COMBA_STEP_BN_MUL_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; @@ -138,7 +134,7 @@ void bn_muld_low(dig_t *c, const dig_t *a, int sa, const dig_t *b, int sb, tmpa = a; tmpb = b + i; for (j = 0; j <= i; j++, tmpa++, tmpb--) { - COMBA_STEP_BN_MUL_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; @@ -150,7 +146,7 @@ void bn_muld_low(dig_t *c, const dig_t *a, int sa, const dig_t *b, int sb, tmpa = a + ++ta; tmpb = b + (sb - 1); for (j = 0; j < sb; j++, tmpa++, tmpb--) { - COMBA_STEP_BN_MUL_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; @@ -161,7 +157,7 @@ void bn_muld_low(dig_t *c, const dig_t *a, int sa, const dig_t *b, int sb, tmpa = a + ++ta; tmpb = b + (sb - 1); for (j = 0; j < sa - ta; j++, tmpa++, tmpb--) { - COMBA_STEP_BN_MUL_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; diff --git a/contrib/relic/src/low/easy/relic_bn_shift_low.c b/contrib/relic/src/low/easy/relic_bn_shift_low.c index e2555162a..d333df931 100644 --- a/contrib/relic/src/low/easy/relic_bn_shift_low.c +++ b/contrib/relic/src/low/easy/relic_bn_shift_low.c @@ -126,3 +126,19 @@ dig_t bn_rshb_low(dig_t *c, const dig_t *a, int size, int bits) { } return carry; } + +dig_t bn_rshs_low(dig_t *c, const dig_t *a, int size, int bits) { + dig_t r, carry, shift, mask; + + /* Prepare the bit mask. */ + shift = (RLC_DIG - bits) % RLC_DIG; + mask = RLC_MASK(bits); + carry = a[size - 1] & mask; + c[size - 1] = (dis_t)a[size - 1] >> bits; + for (int i = size - 2; i >= 0; i--) { + r = a[i] & mask; + c[i] = (a[i] >> bits) | (carry << shift); + carry = r; + } + return carry; +} diff --git a/contrib/relic/src/low/easy/relic_bn_sqr_low.c b/contrib/relic/src/low/easy/relic_bn_sqr_low.c index e52fccf12..ad4872f9f 100644 --- a/contrib/relic/src/low/easy/relic_bn_sqr_low.c +++ b/contrib/relic/src/low/easy/relic_bn_sqr_low.c @@ -32,47 +32,7 @@ #include "relic_bn.h" #include "relic_bn_low.h" - -/*============================================================================*/ -/* Private definitions */ -/*============================================================================*/ - -/** - * Computes the step of a Comba squaring. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - * @param[in] B - the second digit to multiply. - */ -#define COMBA_STEP_BN_SQR_LOW(R2, R1, R0, A, B) \ - dbl_t r = (dbl_t)(A) * (dbl_t)(B); \ - dbl_t s = r + r; \ - dig_t _r = (R1); \ - (R0) += (dig_t)s; \ - (R1) += (R0) < (dig_t)s; \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)(s >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)(s >> (dbl_t)RLC_DIG); \ - (R2) += (s < r); \ - -/** - * Computes the step of a Comba squaring when the loop length is odd. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - */ -#define COMBA_FINAL(R2, R1, R0, A) \ - dbl_t r = (dbl_t)(*tmpa) * (dbl_t)(*tmpa); \ - dig_t _r = (R1); \ - (R0) += (dig_t)(r); \ - (R1) += (R0) < (dig_t)r; \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)(r >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)(r >> (dbl_t)RLC_DIG); \ +#include "relic_util.h" /*============================================================================*/ /* Public definitions */ @@ -81,6 +41,41 @@ dig_t bn_sqra_low(dig_t *c, const dig_t *a, int size) { int i; dig_t c0, c1; + +#ifdef RLC_CONF_NODBL + dig_t r0, r1, _r0, _r1, s0, s1, t, t0, t1; + + t = a[0]; + + /* Accumulate this column with the square of a->dp[i]. */ + RLC_MUL_DIG(_r1, _r0, t, t); + r0 = _r0 + c[0]; + r1 = _r1 + (r0 < _r0); + c[0] = r0; + + /* Update the carry. */ + c0 = r1; + c1 = 0; + + /* Version of the main loop not using double-precision types. */ + for (i = 1; i < size; i++) { + RLC_MUL_DIG(_r1, _r0, t, a[i]); + r0 = _r0 + _r0; + r1 = _r1 + _r1 + (r0 < _r0); + + s0 = r0 + c0; + s1 = r1 + (s0 < r0); + + t0 = s0 + c[i]; + t1 = s1 + (t0 < s0); + c[i] = t0; + + /* Accumulate the old delayed carry. */ + c0 = t1 + c1; + /* Compute the new delayed carry. */ + c1 = (t1 < s1) || (s1 < r1) || (r1 < _r1) || (c0 < c1); + } +#else dbl_t r, r0, r1; /* Accumulate this column with the square of a->dp[i]. */ @@ -91,6 +86,7 @@ dig_t bn_sqra_low(dig_t *c, const dig_t *a, int size) { c0 = (dig_t)(r >> (dbl_t)RLC_DIG); c1 = 0; + /* Version using double-precision types is hopefully faster. */ for (i = 1; i < size; i++) { r = (dbl_t)(a[0]) * (dbl_t)(a[i]); r0 = r + r; @@ -102,6 +98,8 @@ dig_t bn_sqra_low(dig_t *c, const dig_t *a, int size) { /* Compute the new delayed carry. */ c1 = (r0 < r) || (r1 < r0) || (c0 < c1); } +#endif + c[size] += c0; c1 += (c[size] < c0); return c1; @@ -123,10 +121,10 @@ void bn_sqrn_low(dig_t *c, const dig_t *a, int size) { /* Compute the number of additions in this column. */ j = (i + 1); for (j = 0; j < (i + 1) / 2; j++, tmpa++, tmpb--) { - COMBA_STEP_BN_SQR_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_SQR(r2, r1, r0, *tmpa, *tmpb); } if (!(i & 0x01)) { - COMBA_FINAL(r2, r1, r0, *tmpa); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpa); } *c = r0; r0 = r1; @@ -139,10 +137,10 @@ void bn_sqrn_low(dig_t *c, const dig_t *a, int size) { /* Compute the number of additions in this column. */ for (j = 0; j < (size - 1 - i) / 2; j++, tmpa++, tmpb--) { - COMBA_STEP_BN_SQR_LOW(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_SQR(r2, r1, r0, *tmpa, *tmpb); } if (!((size - i) & 0x01)) { - COMBA_FINAL(r2, r1, r0, *tmpa); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpa); } *c = r0; r0 = r1; diff --git a/contrib/relic/src/low/easy/relic_fb_itr_low.c b/contrib/relic/src/low/easy/relic_fb_itr_low.c index 69d476270..a8556a783 100644 --- a/contrib/relic/src/low/easy/relic_fb_itr_low.c +++ b/contrib/relic/src/low/easy/relic_fb_itr_low.c @@ -50,11 +50,7 @@ void fb_itrn_low(dig_t *c, const dig_t *a, dig_t *t) { tmp = a; for (j = 0; j < RLC_FB_DIGS; j++, tmp++) { u = (*tmp >> i) & 0x0F; -#if ALLOC == AUTO p = (t + ((j * RLC_DIG + i) * 4 + u) * RLC_FB_DIGS); -#else - p = ((fb_t *)t)[(j * RLC_DIG + i) * 4 + u]; -#endif fb_addn_low(v, v, p); } } diff --git a/contrib/relic/src/low/easy/relic_fp_inv_low.c b/contrib/relic/src/low/easy/relic_fp_inv_low.c index 4d4bed832..02c43b679 100644 --- a/contrib/relic/src/low/easy/relic_fp_inv_low.c +++ b/contrib/relic/src/low/easy/relic_fp_inv_low.c @@ -43,7 +43,7 @@ void fp_invm_low(dig_t *c, const dig_t *a) { bn_st e; - bn_init(&e, RLC_FP_DIGS); + bn_make(&e, RLC_FP_DIGS); e.used = RLC_FP_DIGS; dv_copy(e.dp, fp_prime_get(), RLC_FP_DIGS); diff --git a/contrib/relic/src/low/easy/relic_fp_mul_low.c b/contrib/relic/src/low/easy/relic_fp_mul_low.c index a6c2d02d5..8295ab618 100644 --- a/contrib/relic/src/low/easy/relic_fp_mul_low.c +++ b/contrib/relic/src/low/easy/relic_fp_mul_low.c @@ -31,65 +31,38 @@ #include "relic_fp.h" #include "relic_fp_low.h" +#include "relic_util.h" /*============================================================================*/ /* Private definitions */ /*============================================================================*/ -/** - * Accumulates a double precision digit in a triple register variable. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - * @param[in] B - the second digit to multiply. - */ -#define COMBA_STEP_MUL(R2, R1, R0, A, B) \ - dbl_t r = (dbl_t)(A) * (dbl_t)(B); \ - dig_t _r = (R1); \ - (R0) += (dig_t)(r); \ - (R1) += (R0) < (dig_t)(r); \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)((r) >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)((r) >> (dbl_t)RLC_DIG); \ - /*============================================================================*/ /* Public definitions */ /*============================================================================*/ dig_t fp_mula_low(dig_t *c, const dig_t *a, dig_t digit) { - int i; - dig_t carry; - dbl_t r; - - carry = 0; - for (i = 0; i < RLC_FP_DIGS; i++, a++, c++) { - /* Multiply the digit *tmpa by b and accumulate with the previous + dig_t _c, r0, r1, carry = 0; + for (int i = 0; i < RLC_FP_DIGS; i++, a++, c++) { + /* Multiply the digit *a by d and accumulate with the previous * result in the same columns and the propagated carry. */ - r = (dbl_t)(*c) + (dbl_t)(*a) * (dbl_t)(digit) + (dbl_t)(carry); + RLC_MUL_DIG(r1, r0, *a, digit); + _c = r0 + carry; + carry = r1 + (_c < carry); /* Increment the column and assign the result. */ - *c = (dig_t)r; + *c = *c + _c; /* Update the carry. */ - carry = (dig_t)(r >> (dbl_t)RLC_DIG); + carry += (*c < _c); } return carry; } dig_t fp_mul1_low(dig_t *c, const dig_t *a, dig_t digit) { - int i; - dig_t carry; - dbl_t r; - - carry = 0; - for (i = 0; i < RLC_FP_DIGS; i++, a++, c++) { - /* Multiply the digit *tmpa by b and accumulate with the previous - * result in the same columns and the propagated carry. */ - r = (dbl_t)(*a) * (dbl_t)(digit) + (dbl_t)(carry); - /* Increment the column and assign the result. */ - *c = (dig_t)r; - /* Update the carry. */ - carry = (dig_t)(r >> (dbl_t)RLC_DIG); + dig_t r0, r1, carry = 0; + for (int i = 0; i < RLC_FP_DIGS; i++, a++, c++) { + RLC_MUL_DIG(r1, r0, *a, digit); + *c = r0 + carry; + carry = r1 + (*c < carry); } return carry; } @@ -104,7 +77,7 @@ void fp_muln_low(dig_t *c, const dig_t *a, const dig_t *b) { tmpa = a; tmpb = b + i; for (j = 0; j <= i; j++, tmpa++, tmpb--) { - COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; @@ -115,7 +88,7 @@ void fp_muln_low(dig_t *c, const dig_t *a, const dig_t *b) { tmpa = a + i + 1; tmpb = b + (RLC_FP_DIGS - 1); for (j = 0; j < RLC_FP_DIGS - (i + 1); j++, tmpa++, tmpb--) { - COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpb); } *c = r0; r0 = r1; diff --git a/contrib/relic/src/low/easy/relic_fp_rdc_low.c b/contrib/relic/src/low/easy/relic_fp_rdc_low.c index 23a28e075..6854aec0a 100644 --- a/contrib/relic/src/low/easy/relic_fp_rdc_low.c +++ b/contrib/relic/src/low/easy/relic_fp_rdc_low.c @@ -34,48 +34,13 @@ #include "relic_fp_low.h" #include "relic_bn_low.h" -/*============================================================================*/ -/* Private definitions */ -/*============================================================================*/ - -/** - * Accumulates a double precision digit in a triple register variable. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - * @param[in] B - the second digit to multiply. - */ -#define COMBA_STEP_RDC(R2, R1, R0, A, B) \ - dbl_t r = (dbl_t)(A) * (dbl_t)(B); \ - dig_t _r = (R1); \ - (R0) += (dig_t)(r); \ - (R1) += (R0) < (dig_t)(r); \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)(r >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)(r >> (dbl_t)RLC_DIG); \ - -/** - * Accumulates a single precision digit in a triple register variable. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to accumulate. - */ -#define COMBA_ADD(R2, R1, R0, A) \ - dig_t __r = (R1); \ - (R0) += (A); \ - (R1) += (R0) < (A); \ - (R2) += (R1) < __r; \ - /*============================================================================*/ /* Public definitions */ /*============================================================================*/ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { - rlc_align dig_t q[2 * RLC_FP_DIGS], _q[2 * RLC_FP_DIGS], t[2 * RLC_FP_DIGS], r[RLC_FP_DIGS]; + rlc_align dig_t q[2 * RLC_FP_DIGS], _q[2 * RLC_FP_DIGS]; + rlc_align dig_t t[2 * RLC_FP_DIGS], r[RLC_FP_DIGS]; const int *sform; int len, first, i, j, k, b0, d0, b1, d1; @@ -128,7 +93,7 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { _q[first - 1] &= RLC_MASK(b0); } if (sform[len - 2] < 0) { - fp_add(r, r, _q); + fp_addm_low(r, r, _q); } else { if (k++ % 2 == 0) { if (fp_subn_low(r, r, _q)) { @@ -147,7 +112,7 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { void fp_rdcn_low(dig_t *c, dig_t *a) { int i, j; - dig_t r0, r1, r2, u, *tmp, *tmpc; + dig_t t, r0, r1, r2, u, *tmp, *tmpc; const dig_t *m, *tmpm; u = *(fp_prime_get_rdc()); @@ -159,11 +124,11 @@ void fp_rdcn_low(dig_t *c, dig_t *a) { tmp = c; tmpm = m + i; for (j = 0; j < i; j++, tmp++, tmpm--) { - COMBA_STEP_RDC(r2, r1, r0, *tmp, *tmpm); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmp, *tmpm); } - COMBA_ADD(r2, r1, r0, *a); + RLC_COMBA_ADD(t, r2, r1, r0, *a); *tmpc = (dig_t)(r0 * u); - COMBA_STEP_RDC(r2, r1, r0, *tmpc, *m); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpc, *m); r0 = r1; r1 = r2; r2 = 0; @@ -173,15 +138,15 @@ void fp_rdcn_low(dig_t *c, dig_t *a) { tmp = c + (i - RLC_FP_DIGS + 1); tmpm = m + RLC_FP_DIGS - 1; for (j = i - RLC_FP_DIGS + 1; j < RLC_FP_DIGS; j++, tmp++, tmpm--) { - COMBA_STEP_RDC(r2, r1, r0, *tmp, *tmpm); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmp, *tmpm); } - COMBA_ADD(r2, r1, r0, *a); + RLC_COMBA_ADD(t, r2, r1, r0, *a); c[i - RLC_FP_DIGS] = r0; r0 = r1; r1 = r2; r2 = 0; } - COMBA_ADD(r2, r1, r0, *a); + RLC_COMBA_ADD(t, r2, r1, r0, *a); c[RLC_FP_DIGS - 1] = r0; if (r1 || dv_cmp(c, m, RLC_FP_DIGS) != RLC_LT) { diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_inv_low.c b/contrib/relic/src/low/easy/relic_fp_smb_low.c similarity index 69% rename from contrib/relic/src/low/x64-asm-254/relic_fp_inv_low.c rename to contrib/relic/src/low/easy/relic_fp_smb_low.c index d9a4d6521..2e35c4f8b 100644 --- a/contrib/relic/src/low/x64-asm-254/relic_fp_inv_low.c +++ b/contrib/relic/src/low/easy/relic_fp_smb_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2013 RELIC Authors + * Copyright (c) 2021 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file @@ -24,13 +24,14 @@ /** * @file * - * Implementation of the low-le&vel in&version functions. + * Implementation of the low-level inversion functions. * * @&version $Id$ * @ingroup fp */ #include "relic_bn.h" +#include "relic_bn_low.h" #include "relic_fp.h" #include "relic_fp_low.h" #include "relic_core.h" @@ -39,35 +40,26 @@ /* Public definitions */ /*============================================================================*/ -int fp_invn_asm(dig_t *, const dig_t *, const dig_t *); +int fp_smbm_low(const dig_t *a) { + bn_st e; + dig_t t[RLC_FP_DIGS]; -void fp_invm_low(dig_t *c, const dig_t *a) { - fp_t t, x1; - int j, k; + bn_make(&e, RLC_FP_DIGS); - fp_null(t); - fp_null(x1); + e.used = RLC_FP_DIGS; + dv_copy(e.dp, fp_prime_get(), RLC_FP_DIGS); + bn_rsh1_low(e.dp, e.dp, RLC_FP_DIGS); +#if AUTO == ALLOC + fp_exp(t, a, &e); +#else + fp_exp(t, (const fp_t)a, &e); +#endif - RLC_TRY { - fp_new(t); - fp_new(x1); + int r = (fp_cmp_dig(t, 1) == RLC_EQ); + fp_negm_low(t, t); + r = RLC_SEL(r, -(fp_cmp_dig(t, 1) == RLC_EQ), !r); - /* u = a, v = p, x1 = 1, x2 = 0, k = 0. */ - k = fp_invn_asm(x1, a, c); - if (k > RLC_FP_DIGS * RLC_DIG) { - t[0] = t[1] = t[2] = t[3] = 0; - k = 512 - k; - j = k % 64; - k = k / 64; - t[k] = (dig_t)1 << j; - fp_mul(c, x1, t); - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t); - fp_free(x1); - } + bn_clean(&e); + + return r; } diff --git a/contrib/relic/src/low/easy/relic_fp_sqr_low.c b/contrib/relic/src/low/easy/relic_fp_sqr_low.c index f201dd8af..6953c2ef0 100644 --- a/contrib/relic/src/low/easy/relic_fp_sqr_low.c +++ b/contrib/relic/src/low/easy/relic_fp_sqr_low.c @@ -32,47 +32,6 @@ #include "relic_fp.h" #include "relic_fp_low.h" -/*============================================================================*/ -/* Private definitions */ -/*============================================================================*/ - -/** - * Computes the step of a Comba squaring. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - * @param[in] B - the second digit to multiply. - */ -#define COMBA_STEP_SQR(R2, R1, R0, A, B) \ - dbl_t r = (dbl_t)(A) * (dbl_t)(B); \ - dbl_t s = r + r; \ - dig_t _r = (R1); \ - (R0) += (dig_t)s; \ - (R1) += (R0) < (dig_t)s; \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)(s >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)(s >> (dbl_t)RLC_DIG); \ - (R2) += (s < r); \ - -/** - * Computes the step of a Comba squaring when the loop length is odd. - * - * @param[in,out] R2 - most significant word of the triple register. - * @param[in,out] R1 - middle word of the triple register. - * @param[in,out] R0 - lowest significant word of the triple register. - * @param[in] A - the first digit to multiply. - */ -#define COMBA_FINAL(R2, R1, R0, A) \ - dbl_t r = (dbl_t)(*tmpa) * (dbl_t)(*tmpa); \ - dig_t _r = (R1); \ - (R0) += (dig_t)(r); \ - (R1) += (R0) < (dig_t)r; \ - (R2) += (R1) < _r; \ - (R1) += (dig_t)(r >> (dbl_t)RLC_DIG); \ - (R2) += (R1) < (dig_t)(r >> (dbl_t)RLC_DIG); \ - /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -92,10 +51,10 @@ void fp_sqrn_low(dig_t *c, const dig_t *a) { /* Compute the number of additions in this column. */ for (j = 0; j < (i + 1) / 2; j++, tmpa++, tmpb--) { - COMBA_STEP_SQR(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_SQR(r2, r1, r0, *tmpa, *tmpb); } if (!(i & 0x01)) { - COMBA_FINAL(r2, r1, r0, *tmpa); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpa); } *c = r0; r0 = r1; @@ -108,10 +67,10 @@ void fp_sqrn_low(dig_t *c, const dig_t *a) { /* Compute the number of additions in this column. */ for (j = 0; j < (RLC_FP_DIGS - 1 - i) / 2; j++, tmpa++, tmpb--) { - COMBA_STEP_SQR(r2, r1, r0, *tmpa, *tmpb); + RLC_COMBA_STEP_SQR(r2, r1, r0, *tmpa, *tmpb); } if (!((RLC_FP_DIGS - i) & 0x01)) { - COMBA_FINAL(r2, r1, r0, *tmpa); + RLC_COMBA_STEP_MUL(r2, r1, r0, *tmpa, *tmpa); } *c = r0; r0 = r1; diff --git a/contrib/relic/src/low/gmp-sec/relic_bn_mul_low.c b/contrib/relic/src/low/gmp-sec/relic_bn_mul_low.c index ee999713b..5fa5d265e 100644 --- a/contrib/relic/src/low/gmp-sec/relic_bn_mul_low.c +++ b/contrib/relic/src/low/gmp-sec/relic_bn_mul_low.c @@ -54,6 +54,24 @@ dig_t bn_mul1_low(dig_t *c, const dig_t *a, dig_t digit, int size) { return u[size]; } +dig_t bn_muls_low(dig_t *c, const dig_t *a, dig_t sa, dis_t digit, int size) { + dig_t _a[size], carry, sign, sd = digit >> (RLC_DIG - 1); + + sa = -sa; + sign = sa ^ sd; + digit = (digit ^ sd) - sd; + + for (size_t i = 0; i < size; i++) { + _a[i] = a[i] ^ sa; + } + bn_add1_low(_a, _a, -sa, size); + carry = bn_mul1_low(c, _a, (dig_t)digit, size); + for (size_t i = 0; i < size; i++) { + c[i] = c[i] ^ sign; + } + return (carry ^ sign) + bn_add1_low(c, c, -sign, size); +} + void bn_muln_low(dig_t *c, const dig_t *a, const dig_t *b, int size) { dig_t *t = RLC_ALLOCA(dig_t, mpn_sec_mul_itch(size, size)); mpn_sec_mul(c, a, size, b, size, t); diff --git a/contrib/relic/src/low/gmp-sec/relic_bn_shift_low.c b/contrib/relic/src/low/gmp-sec/relic_bn_shift_low.c index 4ca729761..5127b3e4a 100644 --- a/contrib/relic/src/low/gmp-sec/relic_bn_shift_low.c +++ b/contrib/relic/src/low/gmp-sec/relic_bn_shift_low.c @@ -56,3 +56,16 @@ dig_t bn_rsh1_low(dig_t *c, const dig_t *a, int size) { dig_t bn_rshb_low(dig_t *c, const dig_t *a, int size, int bits) { return mpn_rshift(c, a, size, bits); } + +dig_t bn_rshs_low(dig_t *c, const dig_t *a, int size, int bits) { + dig_t r, carry, shift, mask; + + /* Prepare the bit mask. */ + shift = (RLC_DIG - bits) % RLC_DIG; + mask = RLC_MASK(bits); + r = a[size - 1] & mask; + c[size - 1] = (dis_t)a[size - 1] >> bits; + carry = mpn_rshift(c, a, size - 1, bits); + c[size - 2] |= (r << shift); + return carry; +} diff --git a/contrib/relic/src/low/gmp-sec/relic_fp_add_low.c b/contrib/relic/src/low/gmp-sec/relic_fp_add_low.c index 943a6a027..66305f681 100644 --- a/contrib/relic/src/low/gmp-sec/relic_fp_add_low.c +++ b/contrib/relic/src/low/gmp-sec/relic_fp_add_low.c @@ -90,7 +90,7 @@ dig_t fp_subd_low(dig_t *c, const dig_t *a, const dig_t *b) { void fp_subc_low(dig_t *c, const dig_t *a, const dig_t *b) { dig_t carry = mpn_sub_n(c, a, b, 2 * RLC_FP_DIGS); - mpn_cnd_sub_n(carry, c + RLC_FP_DIGS, c + RLC_FP_DIGS, + mpn_cnd_add_n(carry, c + RLC_FP_DIGS, c + RLC_FP_DIGS, fp_prime_get(), RLC_FP_DIGS); } @@ -124,6 +124,6 @@ void fp_hlvd_low(dig_t *c, const dig_t *a) { mpn_sec_add_1(c + RLC_FP_DIGS, a + RLC_FP_DIGS, RLC_FP_DIGS, carry, t); carry = mpn_rshift(c + RLC_FP_DIGS, c + RLC_FP_DIGS, RLC_FP_DIGS, 1); mpn_rshift(c, c, RLC_FP_DIGS, 1); - c[RLC_FP_DIGS - 1] ^= ((dig_t)carry << (RLC_DIG - 1)); + c[RLC_FP_DIGS - 1] ^= carry; RLC_FREE(t); } diff --git a/contrib/relic/src/low/gmp-sec/relic_fp_rdc_low.c b/contrib/relic/src/low/gmp-sec/relic_fp_rdc_low.c index e42e9d073..47e225350 100644 --- a/contrib/relic/src/low/gmp-sec/relic_fp_rdc_low.c +++ b/contrib/relic/src/low/gmp-sec/relic_fp_rdc_low.c @@ -42,10 +42,9 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { rlc_align dig_t q[2 * RLC_FP_DIGS], _q[2 * RLC_FP_DIGS]; - rlc_align dig_t _r[2 * RLC_FP_DIGS], r[2 * RLC_FP_DIGS], t[2 * RLC_FP_DIGS]; + rlc_align dig_t t[2 * RLC_FP_DIGS], r[RLC_FP_DIGS]; const int *sform; - int len, first, i, j, b0, d0, b1, d1; - dig_t carry; + int len, first, i, j, k, b0, d0, b1, d1; sform = fp_prime_get_sps(&len); @@ -64,40 +63,47 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { r[first - 1] &= RLC_MASK(b0); } - carry = 0; + k = 0; while (!fp_is_zero(q)) { dv_zero(_q, 2 * RLC_FP_DIGS); for (i = len - 2; i > 0; i--) { j = (sform[i] < 0 ? -sform[i] : sform[i]); RLC_RIP(b1, d1, j); dv_zero(t, 2 * RLC_FP_DIGS); - dv_lshd(t, q, RLC_FP_DIGS, d1); + dv_lshd(t, q, 2 * RLC_FP_DIGS, d1); if (b1 > 0) { bn_lshb_low(t, t, 2 * RLC_FP_DIGS, b1); } - if (sform[i] > 0) { - bn_subn_low(_q, _q, t, 2 * RLC_FP_DIGS); - } else { + /* Check if these two have the same sign. */ + if ((sform[len - 2] < 0) == (sform[i] < 0)) { bn_addn_low(_q, _q, t, 2 * RLC_FP_DIGS); + } else { + bn_subn_low(_q, _q, t, 2 * RLC_FP_DIGS); } } - if (sform[0] > 0) { - bn_subn_low(_q, _q, q, 2 * RLC_FP_DIGS); - } else { + /* Check if these two have the same sign. */ + if ((sform[len - 2] < 0) == (sform[0] < 0)) { bn_addn_low(_q, _q, q, 2 * RLC_FP_DIGS); + } else { + bn_subn_low(_q, _q, q, 2 * RLC_FP_DIGS); } dv_rshd(q, _q, 2 * RLC_FP_DIGS, d0); if (b0 > 0) { bn_rshb_low(q, q, 2 * RLC_FP_DIGS, b0); } - - dv_copy(_r, _q, first); if (b0 > 0) { - _r[first - 1] &= RLC_MASK(b0); + _q[first - 1] &= RLC_MASK(b0); } - carry = fp_addn_low(r, r, _r); - if (carry) { - fp_subn_low(r, r, m); + if (sform[len - 2] < 0) { + fp_addm_low(r, r, _q); + } else { + if (k++ % 2 == 0) { + if (fp_subn_low(r, r, _q)) { + fp_addn_low(r, r, m); + } + } else { + fp_addn_low(r, r, _q); + } } } while (dv_cmp(r, m, RLC_FP_DIGS) != RLC_LT) { diff --git a/contrib/relic/src/low/gmp/relic_bn_mul_low.c b/contrib/relic/src/low/gmp/relic_bn_mul_low.c index 2229b6d2e..a6806a55f 100644 --- a/contrib/relic/src/low/gmp/relic_bn_mul_low.c +++ b/contrib/relic/src/low/gmp/relic_bn_mul_low.c @@ -48,6 +48,24 @@ dig_t bn_mul1_low(dig_t *c, const dig_t *a, dig_t digit, int size) { return mpn_mul_1(c, a, size, digit); } +dig_t bn_muls_low(dig_t *c, const dig_t *a, dig_t sa, dis_t digit, int size) { + dig_t _a[size], carry, sign, sd = digit >> (RLC_DIG - 1); + + sa = -sa; + sign = sa ^ sd; + digit = (digit ^ sd) - sd; + + for (size_t i = 0; i < size; i++) { + _a[i] = a[i] ^ sa; + } + mpn_add_1(_a, _a, size, -sa); + carry = mpn_mul_1(c, _a, size, digit); + for (size_t i = 0; i < size; i++) { + c[i] = c[i] ^ sign; + } + return (carry ^ sign) + mpn_add_1(c, c, size, -sign); +} + void bn_muln_low(dig_t *c, const dig_t *a, const dig_t *b, int size) { mpn_mul_n(c, a, b, size); } diff --git a/contrib/relic/src/low/gmp/relic_bn_shift_low.c b/contrib/relic/src/low/gmp/relic_bn_shift_low.c index 0445b5ab8..eb8ed87b1 100644 --- a/contrib/relic/src/low/gmp/relic_bn_shift_low.c +++ b/contrib/relic/src/low/gmp/relic_bn_shift_low.c @@ -56,3 +56,16 @@ dig_t bn_rsh1_low(dig_t *c, const dig_t *a, int size) { dig_t bn_rshb_low(dig_t *c, const dig_t *a, int size, int bits) { return mpn_rshift(c, a, size, bits); } + +dig_t bn_rshs_low(dig_t *c, const dig_t *a, int size, int bits) { + dig_t r, carry, shift, mask; + + /* Prepare the bit mask. */ + shift = (RLC_DIG - bits) % RLC_DIG; + mask = RLC_MASK(bits); + r = a[size - 1] & mask; + c[size - 1] = (dis_t)a[size - 1] >> bits; + carry = mpn_rshift(c, a, size - 1, bits); + c[size - 2] |= (r << shift); + return carry; +} diff --git a/contrib/relic/src/low/gmp/relic_fp_add_low.c b/contrib/relic/src/low/gmp/relic_fp_add_low.c index a445aa2d9..b5c6dc505 100644 --- a/contrib/relic/src/low/gmp/relic_fp_add_low.c +++ b/contrib/relic/src/low/gmp/relic_fp_add_low.c @@ -124,9 +124,7 @@ void fp_hlvm_low(dig_t *c, const dig_t *a) { dv_copy(c, a, RLC_FP_DIGS); } mpn_rshift(c, c, RLC_FP_DIGS, 1); - if (carry) { - c[RLC_FP_DIGS - 1] ^= ((dig_t)1 << (RLC_DIG - 1)); - } + c[RLC_FP_DIGS - 1] ^= ((dig_t)carry << (RLC_DIG - 1)); } void fp_hlvd_low(dig_t *c, const dig_t *a) { @@ -142,7 +140,5 @@ void fp_hlvd_low(dig_t *c, const dig_t *a) { carry = mpn_rshift(c + RLC_FP_DIGS, c + RLC_FP_DIGS, RLC_FP_DIGS, 1); mpn_rshift(c, c, RLC_FP_DIGS, 1); - if (carry) { - c[RLC_FP_DIGS - 1] ^= ((dig_t)1 << (RLC_DIG - 1)); - } + c[RLC_FP_DIGS - 1] ^= carry; } diff --git a/contrib/relic/src/low/gmp/relic_fp_rdc_low.c b/contrib/relic/src/low/gmp/relic_fp_rdc_low.c index 1b75939cb..d8953cf9c 100644 --- a/contrib/relic/src/low/gmp/relic_fp_rdc_low.c +++ b/contrib/relic/src/low/gmp/relic_fp_rdc_low.c @@ -42,10 +42,9 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { rlc_align dig_t q[2 * RLC_FP_DIGS], _q[2 * RLC_FP_DIGS]; - rlc_align dig_t _r[2 * RLC_FP_DIGS], r[2 * RLC_FP_DIGS], t[2 * RLC_FP_DIGS]; + rlc_align dig_t t[2 * RLC_FP_DIGS], r[RLC_FP_DIGS]; const int *sform; - int len, first, i, j, b0, d0, b1, d1; - dig_t carry; + int len, first, i, j, k, b0, d0, b1, d1; sform = fp_prime_get_sps(&len); @@ -53,7 +52,6 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { first = (d0) + (b0 == 0 ? 0 : 1); /* q = floor(a/b^k) */ - dv_zero(q, 2 * RLC_FP_DIGS); dv_rshd(q, a, 2 * RLC_FP_DIGS, d0); if (b0 > 0) { bn_rshb_low(q, q, 2 * RLC_FP_DIGS, b0); @@ -65,40 +63,47 @@ void fp_rdcs_low(dig_t *c, const dig_t *a, const dig_t *m) { r[first - 1] &= RLC_MASK(b0); } - carry = 0; + k = 0; while (!fp_is_zero(q)) { dv_zero(_q, 2 * RLC_FP_DIGS); for (i = len - 2; i > 0; i--) { j = (sform[i] < 0 ? -sform[i] : sform[i]); RLC_RIP(b1, d1, j); dv_zero(t, 2 * RLC_FP_DIGS); - dv_lshd(t, q, RLC_FP_DIGS, d1); + dv_lshd(t, q, 2 * RLC_FP_DIGS, d1); if (b1 > 0) { bn_lshb_low(t, t, 2 * RLC_FP_DIGS, b1); } - if (sform[i] > 0) { - bn_subn_low(_q, _q, t, 2 * RLC_FP_DIGS); - } else { + /* Check if these two have the same sign. */ + if ((sform[len - 2] < 0) == (sform[i] < 0)) { bn_addn_low(_q, _q, t, 2 * RLC_FP_DIGS); + } else { + bn_subn_low(_q, _q, t, 2 * RLC_FP_DIGS); } } - if (sform[0] > 0) { - bn_subn_low(_q, _q, q, 2 * RLC_FP_DIGS); - } else { + /* Check if these two have the same sign. */ + if ((sform[len - 2] < 0) == (sform[0] < 0)) { bn_addn_low(_q, _q, q, 2 * RLC_FP_DIGS); + } else { + bn_subn_low(_q, _q, q, 2 * RLC_FP_DIGS); } dv_rshd(q, _q, 2 * RLC_FP_DIGS, d0); if (b0 > 0) { bn_rshb_low(q, q, 2 * RLC_FP_DIGS, b0); } - - dv_copy(_r, _q, first); if (b0 > 0) { - _r[first - 1] &= RLC_MASK(b0); + _q[first - 1] &= RLC_MASK(b0); } - carry = fp_addn_low(r, r, _r); - if (carry) { - fp_subn_low(r, r, m); + if (sform[len - 2] < 0) { + fp_addm_low(r, r, _q); + } else { + if (k++ % 2 == 0) { + if (fp_subn_low(r, r, _q)) { + fp_addn_low(r, r, m); + } + } else { + fp_addn_low(r, r, _q); + } } } while (dv_cmp(r, m, RLC_FP_DIGS) != RLC_LT) { diff --git a/contrib/relic/src/low/msp-asm/relic_bn_add_low.c b/contrib/relic/src/low/msp-asm/relic_bn_add_low.c index 4b810145c..9c8ec9679 100644 --- a/contrib/relic/src/low/msp-asm/relic_bn_add_low.c +++ b/contrib/relic/src/low/msp-asm/relic_bn_add_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_bn_shift_low.c b/contrib/relic/src/low/msp-asm/relic_bn_shift_low.c index fc462c662..3f784c556 100644 --- a/contrib/relic/src/low/msp-asm/relic_bn_shift_low.c +++ b/contrib/relic/src/low/msp-asm/relic_bn_shift_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_add_low.c b/contrib/relic/src/low/msp-asm/relic_fb_add_low.c index d6fd6c432..07a50dc9f 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_add_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fb_add_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_add_low.s b/contrib/relic/src/low/msp-asm/relic_fb_add_low.s index e6b228d3f..89938d4ca 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_add_low.s +++ b/contrib/relic/src/low/msp-asm/relic_fb_add_low.s @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_mul_low.c b/contrib/relic/src/low/msp-asm/relic_fb_mul_low.c index d1c64a96b..b79bdda9d 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_mul_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fb_mul_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_rdc_low.c b/contrib/relic/src/low/msp-asm/relic_fb_rdc_low.c index 786ccce0f..9c6567d4e 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_rdc_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fb_rdc_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_shift_low.c b/contrib/relic/src/low/msp-asm/relic_fb_shift_low.c index cf8a71aa9..593445682 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_shift_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fb_shift_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.c b/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.c index 2f54af0b9..5cfac64c4 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.s b/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.s index 168cf7234..eb3a89c24 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.s +++ b/contrib/relic/src/low/msp-asm/relic_fb_sqr_low.s @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fb_srt_low.c b/contrib/relic/src/low/msp-asm/relic_fb_srt_low.c index d8f7873d3..a2d0195a0 100644 --- a/contrib/relic/src/low/msp-asm/relic_fb_srt_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fb_srt_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file @@ -289,7 +289,7 @@ const uint8_t fb_srt_table_evens[256] = { 0, 1, 16, 17, 2, 3, 18, 19, 32, 33, const uint8_t fb_srt_table_odds[256] = { 0, 16, 1, 17, 32, 48, 33, 49, 2, 18, 3, 19, 34, 50, 35, 51, 64, 80, 65, 81, 96, 112, 97, 113, 66, 82, 67, 83, 98, 114, 99, 115, 4, 20, 5, 21, 36, 52, 37, 53, 6, 22, 7, 23, 38, 54, 39, 55, - 68, 84, 69, 85, 100, 116, 101, 117, 70, 86, 71, 87, 102, 118, 103, 119, 128, + 68, 84, 69, 85, 100, 116, 101, 117, 70, 86, 71, 87, 102, 118, 103, 119, 128, 144, 129, 145, 160, 176, 161, 177, 130, 146, 131, 147, 162, 178, 163, 179, 192, 208, 193, 209, 224, 240, 225, 241, 194, 210, 195, 211, 226, 242, 227, 243, 132, 148, 133, 149, 164, 180, 165, 181, 134, 150, 135, 151, 166, 182, @@ -303,4 +303,4 @@ const uint8_t fb_srt_table_odds[256] = { 0, 16, 1, 17, 32, 48, 33, 49, 2, 18, 3, 141, 157, 172, 188, 173, 189, 142, 158, 143, 159, 174, 190, 175, 191, 204, 220, 205, 221, 236, 252, 237, 253, 206, 222, 207, 223, 238, 254, 239, 255 }; -#endif \ No newline at end of file +#endif diff --git a/contrib/relic/src/low/msp-asm/relic_fp_add_low.c b/contrib/relic/src/low/msp-asm/relic_fp_add_low.c index 0313295f6..02d8c22ca 100644 --- a/contrib/relic/src/low/msp-asm/relic_fp_add_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fp_add_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fp_inv_low.c b/contrib/relic/src/low/msp-asm/relic_fp_inv_low.c index b111c90f4..5b94516d7 100644 --- a/contrib/relic/src/low/msp-asm/relic_fp_inv_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fp_inv_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007, 2008, 2009 RELIC Authors + * Copyright (c) 2012 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/msp-asm/relic_fpx_add_low.c b/contrib/relic/src/low/msp-asm/relic_fpx_add_low.c index 0efe96e46..be614e595 100644 --- a/contrib/relic/src/low/msp-asm/relic_fpx_add_low.c +++ b/contrib/relic/src/low/msp-asm/relic_fpx_add_low.c @@ -1,6 +1,6 @@ /* * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2007-2011 RELIC Authors + * Copyright (c) 2014 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_inv_low.s b/contrib/relic/src/low/x64-asm-254/relic_fp_inv_low.s deleted file mode 100644 index 76124434f..000000000 --- a/contrib/relic/src/low/x64-asm-254/relic_fp_inv_low.s +++ /dev/null @@ -1,338 +0,0 @@ -/* - * RELIC is an Efficient LIbrary for Cryptography - * Copyright (c) 2013 RELIC Authors - * - * This file is part of RELIC. RELIC is legal property of its developers, - * whose names are not listed here. Please refer to the COPYRIGHT file - * for contact information. - * - * RELIC is free software; you can redistribute it and/or modify it under the - * terms of the version 2.1 (or later) of the GNU Lesser General Public License - * as published by the Free Software Foundation; or version 2.0 of the Apache - * License as published by the Apache Software Foundation. See the LICENSE files - * for more details. - * - * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the LICENSE files for more details. - * - * You should have received a copy of the GNU Lesser General Public or the - * Apache License along with RELIC. If not, see - * or . - */ - -/** - * @file - * - * Implementation of the low-level inversion functions. - * - * @&version $Id$ - * @ingroup fp - */ - -#include "macro.s" - -/*============================================================================*/ -/* Public definitions */ -/*============================================================================*/ - -/* No carry */ -.macro DBLN R - addq %rdi,%rdi - adcq %rdx,%rdx - adcq %rsi,%rsi - adcq %rcx,%rcx -.endm - -.macro DBLN2 R - addq %rdi,%rdi - adcq %rdx,%rdx -.endm - -.macro DBLN3 R - addq %rdi,%rdi - adcq %rdx,%rdx - adcq %rsi,%rsi -.endm - -#define P0 $0xA700000000000013 -#define P1 $0x6121000000000013 -#define P2 $0xBA344D8000000008 -#define P3 $0x2523648240000001 - -#define Q3 $0x1B0A32FDF6403A3D -#define Q2 $0x281E3A1B7F86954F -#define Q1 $0x55EFBF6E8C1CC3F1 -#define Q0 $0xB3E886745370473D - -#define R0 $0x15FFFFFFFFFFFF8E -#define R1 $0xB939FFFFFFFFFF8A -#define R2 $0xA2C62EFFFFFFFFCD -#define R3 $0x212BA4F27FFFFFF5 - -.global cdecl(fp_invn_asm) - -/** - * rdi = a, rsi = x1, rdx = c - */ -cdecl(fp_invn_asm): - push %r12 - push %r13 - push %r14 - push %r15 - push %rbp - push %rbx - push %rdi - subq $96, %rsp - - xorq %rax, %rax - movq P0,%r12 - movq P1,%r13 - movq P2,%r14 - movq P3,%r15 - - movq 0(%rsi),%rbp - movq 8(%rsi),%rbx - movq 16(%rsi),%rcx - movq 24(%rsi),%rsi - - movq R0,%r8 - movq %r8,0(%rdx) - movq R1,%r9 - movq %r9,8(%rdx) - movq R2,%r10 - movq %r10,16(%rdx) - movq R3,%r11 - movq %r11,24(%rdx) - - movq $1,%rdi - xorq %r8, %r8 - xorq %r9, %r9 - xorq %r10, %r10 - xorq %rdx, %rdx - -loop: - movq %r15,%r11 - orq %rsi,%r11 - jz loop2 - inc %rax - test $1, %r12 - jnz v_odd - shrd $1, %r13, %r12 - shrd $1, %r14, %r13 - shrd $1, %r15, %r14 - shr $1, %r15 - DBLN2 %rsp - jmp loop -v_odd: - test $1, %rbp - jnz u_odd - shrd $1, %rbx, %rbp - shrd $1, %rcx, %rbx - shrd $1, %rsi, %rcx - shr $1, %rsi - addq %r8,%r8 - adcq %r9,%r9 - jmp loop -u_odd: - subq %rbp, %r12 - sbbq %rbx, %r13 - sbbq %rcx, %r14 - sbbq %rsi, %r15 - jc cmp_lt - shrd $1, %r13, %r12 - shrd $1, %r14, %r13 - shrd $1, %r15, %r14 - shr $1, %r15 - addq %rdi,%r8 - adcq %rdx,%r9 - DBLN2 %rsp - jmp loop -cmp_lt: - addq %rbp, %r12 - adcq %rbx, %r13 - adcq %rcx, %r14 - adcq %rsi, %r15 - subq %r12, %rbp - sbbq %r13, %rbx - sbbq %r14, %rcx - sbbq %r15, %rsi - shrd $1, %rbx, %rbp - shrd $1, %rcx, %rbx - shrd $1, %rsi, %rcx - shr $1, %rsi - addq %r8,%rdi - adcq %r9,%rdx - addq %r8,%r8 - adcq %r9,%r9 - jmp loop - -loop2: - movq %r14,%r11 - orq %rcx,%r11 - jz loop3 - inc %rax - test $1, %r12 - jnz v_odd2 - shrd $1, %r13, %r12 - shrd $1, %r14, %r13 - shr $1, %r14 - DBLN3 %rsp - jmp loop2 -v_odd2: - test $1, %rbp - jnz u_odd2 - shrd $1, %rbx, %rbp - shrd $1, %rcx, %rbx - shr $1, %rcx - addq %r8,%r8 - adcq %r9,%r9 - adcq %r10,%r10 - jmp loop2 -u_odd2: - subq %rbp, %r12 - sbbq %rbx, %r13 - sbbq %rcx, %r14 - jc cmp_lt2 - shrd $1, %r13, %r12 - shrd $1, %r14, %r13 - shr $1, %r14 - addq %rdi,%r8 - adcq %rdx,%r9 - adcq %rsi,%r10 - DBLN3 %rsp - jmp loop2 -cmp_lt2: - addq %rbp, %r12 - adcq %rbx, %r13 - adcq %rcx, %r14 - subq %r12, %rbp - sbbq %r13, %rbx - sbbq %r14, %rcx - shrd $1, %rbx, %rbp - shrd $1, %rcx, %rbx - shr $1, %rcx - addq %r8,%rdi - adcq %r9,%rdx - adcq %r10,%rsi - addq %r8,%r8 - adcq %r9,%r9 - adcq %r10,%r10 - jmp loop2 - -loop3: - movq %r13,%r11 - orq %rbx,%r11 - jz loop4 - inc %rax - test $1, %r12 - jnz v_odd3 - shrd $1, %r13, %r12 - shr $1, %r13 - DBLN %rsp - jmp loop3 -v_odd3: - test $1, %rbp - jnz u_odd3 - shrd $1, %rbx, %rbp - shr $1, %rbx - addq %r8,%r8 - adcq %r9,%r9 - adcq %r10,%r10 - adcq %r15,%r15 - jmp loop3 -u_odd3: - subq %rbp, %r12 - sbbq %rbx, %r13 - jc cmp_lt3 - shrd $1, %r13, %r12 - shr $1, %r13 - addq %rdi,%r8 - adcq %rdx,%r9 - adcq %rsi,%r10 - adcq %rcx,%r15 - DBLN %rsp - jmp loop3 -cmp_lt3: - addq %rbp, %r12 - adcq %rbx, %r13 - subq %r12, %rbp - sbbq %r13, %rbx - shrd $1, %rbx, %rbp - shr $1, %rbx - addq %r8,%rdi - adcq %r9,%rdx - adcq %r10,%rsi - adcq %r15,%rcx - addq %r8,%r8 - adcq %r9,%r9 - adcq %r10,%r10 - adcq %r15,%r15 - jmp loop3 - -loop4: - movq %r12,%r11 - orq %r12,%r11 - jz end - inc %rax - test $1, %r12 - jnz v_odd4 - shr $1, %r12 - DBLN %rsp - jmp loop4 -v_odd4: - test $1, %rbp - jnz u_odd4 - shrd $1, %rbx, %rbp - shr $1, %rbx - addq %r8,%r8 - adcq %r9,%r9 - adcq %r10,%r10 - adcq %r15,%r15 - jmp loop4 -u_odd4: - subq %rbp, %r12 - jc cmp_lt4 - shr $1, %r12 - addq %rdi,%r8 - adcq %rdx,%r9 - adcq %rsi,%r10 - adcq %rcx,%r15 - DBLN %rsp - jmp loop4 -cmp_lt4: - addq %rbp, %r12 - subq %r12, %rbp - shr $1, %rbp - addq %r8,%rdi - adcq %r9,%rdx - adcq %r10,%rsi - adcq %r15,%rcx - addq %r8,%r8 - adcq %r9,%r9 - adcq %r10,%r10 - adcq %r15,%r15 - jmp loop4 - -end: - movq Q0,%r12 - movq Q1,%r13 - movq Q2,%r14 - movq Q3,%r15 - movq %rax,%rbx - movq %rsp,%rbp - movq %rdx,0(%rsp) - addq $32,%rbp - FP_MULN_LOW %rbp, %r8, %r9, %r10, %rdi, 0(%rsp), %rsi, %rcx, %r12, %r13, %r14, %r15 - addq $96, %rsp - pop %rdi - FP_RDCN_LOW %rdi, %rbp - movq %rbx,%rax -exit: - pop %rbx - pop %rbp - pop %r15 - pop %r14 - pop %r13 - pop %r12 - ret diff --git a/contrib/relic/src/low/x64-asm-254/CMakeLists.txt b/contrib/relic/src/low/x64-asm-4l/CMakeLists.txt similarity index 100% rename from contrib/relic/src/low/x64-asm-254/CMakeLists.txt rename to contrib/relic/src/low/x64-asm-4l/CMakeLists.txt diff --git a/contrib/relic/src/low/x64-asm-254/macro.s b/contrib/relic/src/low/x64-asm-4l/macro.s similarity index 68% rename from contrib/relic/src/low/x64-asm-254/macro.s rename to contrib/relic/src/low/x64-asm-4l/macro.s index 7f4e9558b..c6f836230 100755 --- a/contrib/relic/src/low/x64-asm-254/macro.s +++ b/contrib/relic/src/low/x64-asm-4l/macro.s @@ -31,12 +31,24 @@ * @ingroup fp */ +#if FP_PRIME == 254 + #define P0 $0xA700000000000013 #define P1 $0x6121000000000013 #define P2 $0xBA344D8000000008 #define P3 $0x2523648240000001 #define U0 $0x08435E50D79435E5 +#elif FP_PRIME == 255 + +#define P0 $0xFFFFFFFFFFFFFFED +#define P1 $0xFFFFFFFFFFFFFFFF +#define P2 $0xFFFFFFFFFFFFFFFF +#define P3 $0x7FFFFFFFFFFFFFFF +#define U0 $0x86BCA1AF286BCA1B + +#endif + #define NP40 $0xC000000000000000 #define NP41 $0xE9C0000000000004 #define NP42 $0x1848400000000004 @@ -102,6 +114,8 @@ .endif .endm +#if FP_PRIME == 254 + /* Montgomery reduction, comba, optimized for BN254 */ .macro FP_RDCN_LOW C, A xorq %r10, %r10 @@ -253,6 +267,166 @@ movq %rcx,24(\C) .endm +#else + +/* Montgomery reduction, comba, optimized for BN254 */ +.macro FP_RDCN_LOW C, A + xorq %r10, %r10 + movq U0, %rcx +// i=0 + movq 0(\A), %r8 + movq %r8, %rax + mulq %rcx // v*U0 + movq %rax, %r14 + movq P0, %r11 + mulq %r11 // z0*m0 + addq %rax,%r8 + movq P1, %r12 + adcq 8(\A),%rdx + movq %rdx,%r9 + adcq $0,%r10 +// i=1, j=0 + movq %r14, %rax + mulq %r12 // z0*m1 + addq %rax,%r9 + movq %r9, %rax + adcq %rdx,%r10 + + mulq %rcx // v*U0 + movq %rax, 8(\A) + xorq %r8,%r8 + mulq %r11 // z1*m0 + addq %rax,%r9 + movq P2, %r13 + adcq %rdx,%r10 + adcq $0,%r8 +// i=2, j=0,1 + movq %r14, %rax + mulq %r13 // z0*m2 + addq 16(\A),%r10 + adcq $0,%r8 + + addq %rax,%r10 + adcq %rdx,%r8 + + xorq %r9,%r9 + movq 8(\A), %rax + mulq %r12 // z1*m1 + addq %rax,%r10 + adcq %rdx,%r8 + adcq $0,%r9 + movq %r10, %rax + mulq %rcx // v*U0 + movq %rax, 16(\A) + mulq %r11 // z2*m0 + addq %rax,%r10 + movq %r14, %rax + adcq %rdx,%r8 + movq P3, %r14 + adcq $0,%r9 +// i=3, j=0,1,2 + mulq %r14 // z0*m3 + addq 24(\A),%r8 + adcq $0,%r9 + + xorq %r10, %r10 + addq %rax,%r8 + adcq %rdx,%r9 + adcq $0,%r10 + + movq 8(\A), %rax + mulq %r13 // z1*m2 + addq %rax,%r8 + movq 16(\A), %rax + adcq %rdx,%r9 + adcq $0,%r10 + + mulq %r12 // z2*m1 + addq %rax,%r8 + movq %r8, %rax + adcq %rdx,%r9 + adcq $0,%r10 + + mulq %rcx // v*U0 + movq %rax, 24(\A) + mulq %r11 // z3*m0 + addq %rax,%r8 + adcq %rdx,%r9 + adcq $0,%r10 +// loop 2 +// i=4, j=1,2,3 + movq 8(\A), %rax + mulq %r14 // z1*m3 + addq 32(\A),%r9 + adcq $0,%r10 + + xorq %r8, %r8 + addq %rax,%r9 + adcq %rdx,%r10 + adcq $0,%r8 + + movq 16(\A), %rax + mulq %r13 // z2*m2 + addq %rax,%r9 + adcq %rdx,%r10 + adcq $0,%r8 + movq 24(\A), %rax + + mulq %r12 // z3*m1 + addq %rax,%r9 + adcq %rdx,%r10 + movq %r9,%r12 // Z0 + adcq $0,%r8 +// i=5, j=2,3 + xorq %r11, %r11 + movq 16(\A), %rax + mulq %r14 // z2*m3 + addq %rax,%r10 + adcq %rdx,%r8 + adcq $0,%r11 + + movq 24(\A), %rax + mulq %r13 // z3*m2 + addq %rax,%r10 + adcq %rdx,%r8 + adcq $0,%r11 + + addq 40(\A),%r10 + movq %r10,%r13 // Z1 + adcq $0,%r8 +// i=6, j=3 + movq 24(\A), %rax + mulq %r14 // z3*m3 + addq %rax,%r8 + adcq %rdx,%r11 + + addq 48(\A),%r8 + movq %r8,%r14 // Z2 + adcq $0,%r11 + + addq 56(\A),%r11 + movq %r11,%rcx // Z3 + + movq P0,%rax + subq %rax,%r9 + movq P1,%rax + sbbq %rax,%r10 + movq P2,%rax + sbbq %rax,%r8 + movq P3,%rax + sbbq %rax,%r11 + cmovnc %r9,%r12 + movq %r12,0(\C) + cmovnc %r10,%r13 + movq %r13,8(\C) + cmovnc %r8,%r14 + movq %r14,16(\C) + cmovnc %r11,%rcx + movq %rcx,24(\C) +.endm + +#endif + .macro FP_MULN_LOW C, R0, R1, R2, A0, A1, A2, A3, B0, B1, B2, B3 movq \A0,%rax mulq \B0 diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_add_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fp_add_low.s similarity index 96% rename from contrib/relic/src/low/x64-asm-254/relic_fp_add_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fp_add_low.s index b2f18b111..ab2ae7fa3 100755 --- a/contrib/relic/src/low/x64-asm-254/relic_fp_add_low.s +++ b/contrib/relic/src/low/x64-asm-4l/relic_fp_add_low.s @@ -35,6 +35,7 @@ #include "macro.s" .text + .global cdecl(fp_add1_low) .global cdecl(fp_addn_low) .global cdecl(fp_addm_low) @@ -289,27 +290,31 @@ cdecl(fp_subd_low): ret cdecl(fp_negm_low): - movq 0(%rsi) , %r8 - or 8(%rsi) , %r8 - or 16(%rsi), %r8 - or 24(%rsi), %r8 + xorq %rax, %rax mov P0, %rcx mov P1, %r9 mov P2, %r10 mov P3, %r11 + subq 0(%rsi) , %rcx + sbbq 8(%rsi) , %r9 + sbbq 16(%rsi) , %r10 + sbbq 24(%rsi) , %r11 + + movq 0(%rsi) , %r8 + or 8(%rsi) , %r8 + or 16(%rsi), %r8 + or 24(%rsi), %r8 test %r8, %r8 - cmovnz %rcx , %r8 - subq 0(%rsi) , %r8 - movq %r8 , 0(%rdi) - cmovnz %r9 , %r8 - sbbq 8(%rsi) , %r8 - movq %r8 , 8(%rdi) - cmovnz %r10 , %r8 - sbbq 16(%rsi), %r8 - movq %r8 , 16(%rdi) - cmovnz %r11 , %r8 - sbbq 24(%rsi), %r8 - movq %r8 , 24(%rdi) + + cmovnz %rcx, %rax + movq %rax, 0(%rdi) + cmovnz %r9, %rax + movq %rax, 8(%rdi) + cmovnz %r10, %rax + movq %rax, 16(%rdi) + cmovnz %r11, %rax + movq %rax, 24(%rdi) + ret cdecl(fp_dbln_low): diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_inv_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fp_inv_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_inv_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fp_inv_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_mul_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fp_mul_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_mul_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fp_mul_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_mul_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fp_mul_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_mul_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fp_mul_low.s diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_rdc_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fp_rdc_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_rdc_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fp_rdc_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_rdc_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fp_rdc_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_rdc_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fp_rdc_low.s diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_shift_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fp_shift_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_shift_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fp_shift_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_shift_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fp_shift_low.s similarity index 99% rename from contrib/relic/src/low/x64-asm-254/relic_fp_shift_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fp_shift_low.s index 595f5175a..1ecfc09e9 100755 --- a/contrib/relic/src/low/x64-asm-254/relic_fp_shift_low.s +++ b/contrib/relic/src/low/x64-asm-4l/relic_fp_shift_low.s @@ -45,7 +45,6 @@ cdecl(fp_rsh1_low): ret cdecl(fp_lsh1_low): -fp_lsh1_low: movq 0(%rsi), %r8 movq 8(%rsi), %r9 movq 16(%rsi), %r10 diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_sqr_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fp_sqr_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_sqr_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fp_sqr_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fp_sqr_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fp_sqr_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fp_sqr_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fp_sqr_low.s diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_add_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fpx_add_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_add_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_add_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_add_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fpx_add_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_add_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_add_low.s diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_mul_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fpx_mul_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_mul_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_mul_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_mul_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fpx_mul_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_mul_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_mul_low.s diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_rdc_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fpx_rdc_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_rdc_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_rdc_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_rdc_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fpx_rdc_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_rdc_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_rdc_low.s diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_sqr_low.c b/contrib/relic/src/low/x64-asm-4l/relic_fpx_sqr_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_sqr_low.c rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_sqr_low.c diff --git a/contrib/relic/src/low/x64-asm-254/relic_fpx_sqr_low.s b/contrib/relic/src/low/x64-asm-4l/relic_fpx_sqr_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-254/relic_fpx_sqr_low.s rename to contrib/relic/src/low/x64-asm-4l/relic_fpx_sqr_low.s diff --git a/contrib/relic/src/low/x64-asm-382/CMakeLists.txt b/contrib/relic/src/low/x64-asm-6l/CMakeLists.txt similarity index 100% rename from contrib/relic/src/low/x64-asm-382/CMakeLists.txt rename to contrib/relic/src/low/x64-asm-6l/CMakeLists.txt diff --git a/contrib/relic/src/low/x64-asm-382/macro.s b/contrib/relic/src/low/x64-asm-6l/macro.s similarity index 95% rename from contrib/relic/src/low/x64-asm-382/macro.s rename to contrib/relic/src/low/x64-asm-6l/macro.s index 9c1dfb375..e477e69ed 100644 --- a/contrib/relic/src/low/x64-asm-382/macro.s +++ b/contrib/relic/src/low/x64-asm-6l/macro.s @@ -40,7 +40,7 @@ #define P4 0x4B1BA7B6434BACD7 #define P5 0x1A0111EA397FE69A #define U0 0x89F3FFFCFFFCFFFD -#else +#elif FP_PRIME == 382 #define P0 0x004E000000000013 #define P1 0x09480097801382BE #define P2 0xA6E58DBE43002A06 @@ -48,6 +48,14 @@ #define P4 0x2D996CC179C6D166 #define P5 0x24009015183F9489 #define U0 0xDF615E50D79435E5 +#elif FP_PRIME == 383 +#define P0 0xDA371D6485AAB0AB +#define P1 0x7A8C3F298A64852B +#define P2 0xAC31B801696124F4 +#define P3 0xA0AD462CF365A511 +#define P4 0xA06DADC41FEA9284 +#define P5 0x5565569564AB6EB5 +#define U0 0x69BC0571073435FD #endif .text diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_add_low.s b/contrib/relic/src/low/x64-asm-6l/relic_fp_add_low.s similarity index 99% rename from contrib/relic/src/low/x64-asm-382/relic_fp_add_low.s rename to contrib/relic/src/low/x64-asm-6l/relic_fp_add_low.s index 0c9565a6c..d49e8438f 100644 --- a/contrib/relic/src/low/x64-asm-382/relic_fp_add_low.s +++ b/contrib/relic/src/low/x64-asm-6l/relic_fp_add_low.s @@ -51,6 +51,8 @@ p5: .quad P5 .global p4 .global p5 +#if OPSYS != WINDOWS + .hidden p0 .hidden p1 .hidden p2 @@ -58,6 +60,8 @@ p5: .quad P5 .hidden p4 .hidden p5 +#endif + .text .global fp_add1_low diff --git a/contrib/relic/src/low/x64-asm-6l/relic_fp_inv_low.c b/contrib/relic/src/low/x64-asm-6l/relic_fp_inv_low.c new file mode 100644 index 000000000..b3276603e --- /dev/null +++ b/contrib/relic/src/low/x64-asm-6l/relic_fp_inv_low.c @@ -0,0 +1,70 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2017 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of the low-level inversion functions. + * + * @&version $Id$ + * @ingroup fp + */ + +#include + +#include "relic_fp.h" +#include "relic_fp_low.h" +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void fp_invm_low(dig_t *c, const dig_t *a) { + mp_size_t cn; + rlc_align dig_t s[RLC_FP_DIGS], t[2 * RLC_FP_DIGS], u[RLC_FP_DIGS + 1]; + +#if FP_RDC == MONTY + dv_zero(t + RLC_FP_DIGS, RLC_FP_DIGS); + dv_copy(t, a, RLC_FP_DIGS); + fp_rdcn_low(u, t); +#else + fp_copy(u, a); +#endif + + dv_copy(s, fp_prime_get(), RLC_FP_DIGS); + + mpn_gcdext(t, c, &cn, u, RLC_FP_DIGS, s, RLC_FP_DIGS); + if (cn < 0) { + dv_zero(c - cn, RLC_FP_DIGS + cn); + mpn_sub_n(c, fp_prime_get(), c, RLC_FP_DIGS); + } else { + dv_zero(c + cn, RLC_FP_DIGS - cn); + } + +#if FP_RDC == MONTY + dv_zero(t, RLC_FP_DIGS); + dv_copy(t + RLC_FP_DIGS, c, RLC_FP_DIGS); + mpn_tdiv_qr(u, c, 0, t, 2 * RLC_FP_DIGS, fp_prime_get(), RLC_FP_DIGS); +#endif +} diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_mul_low.c b/contrib/relic/src/low/x64-asm-6l/relic_fp_mul_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_mul_low.c rename to contrib/relic/src/low/x64-asm-6l/relic_fp_mul_low.c diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_mul_low.s b/contrib/relic/src/low/x64-asm-6l/relic_fp_mul_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_mul_low.s rename to contrib/relic/src/low/x64-asm-6l/relic_fp_mul_low.s diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_rdc_low.c b/contrib/relic/src/low/x64-asm-6l/relic_fp_rdc_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_rdc_low.c rename to contrib/relic/src/low/x64-asm-6l/relic_fp_rdc_low.c diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_rdc_low.s b/contrib/relic/src/low/x64-asm-6l/relic_fp_rdc_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_rdc_low.s rename to contrib/relic/src/low/x64-asm-6l/relic_fp_rdc_low.s diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_shift_low.c b/contrib/relic/src/low/x64-asm-6l/relic_fp_shift_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_shift_low.c rename to contrib/relic/src/low/x64-asm-6l/relic_fp_shift_low.c diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_shift_low.s b/contrib/relic/src/low/x64-asm-6l/relic_fp_shift_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_shift_low.s rename to contrib/relic/src/low/x64-asm-6l/relic_fp_shift_low.s diff --git a/contrib/relic/src/low/x64-asm-6l/relic_fp_smb_low.c b/contrib/relic/src/low/x64-asm-6l/relic_fp_smb_low.c new file mode 100644 index 000000000..d25200282 --- /dev/null +++ b/contrib/relic/src/low/x64-asm-6l/relic_fp_smb_low.c @@ -0,0 +1,67 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of the low-level inversion functions. + * + * @&version $Id$ + * @ingroup fp + */ + +#include + +#include "relic_fp.h" +#include "relic_fp_low.h" +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int fp_smbm_low(const dig_t *a) { + mpz_t n, p; + rlc_align dig_t t[2 * RLC_FP_DIGS], u[RLC_FP_DIGS]; + int res; + + mpz_init(n); + mpz_init(p); + +#if FP_RDC == MONTY + dv_zero(t + RLC_FP_DIGS, RLC_FP_DIGS); + dv_copy(t, a, RLC_FP_DIGS); + fp_rdcn_low(u, t); +#else + fp_copy(u, a); +#endif + + mpz_import(n, RLC_FP_DIGS, -1, sizeof(dig_t), 0, 0, u); + mpz_import(p, RLC_FP_DIGS, -1, sizeof(dig_t), 0, 0, fp_prime_get()); + + res = mpz_jacobi(n, p); + + mpz_clear(n); + mpz_clear(p); + return res; +} diff --git a/contrib/relic/src/low/x64-asm-382/relic_fp_sqr_low.c b/contrib/relic/src/low/x64-asm-6l/relic_fp_sqr_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-382/relic_fp_sqr_low.c rename to contrib/relic/src/low/x64-asm-6l/relic_fp_sqr_low.c diff --git a/contrib/relic/src/low/x64-asm-511/CMakeLists.txt b/contrib/relic/src/low/x64-asm-8l/CMakeLists.txt similarity index 100% rename from contrib/relic/src/low/x64-asm-511/CMakeLists.txt rename to contrib/relic/src/low/x64-asm-8l/CMakeLists.txt diff --git a/contrib/relic/src/low/x64-asm-511/macro.s b/contrib/relic/src/low/x64-asm-8l/macro.s similarity index 95% rename from contrib/relic/src/low/x64-asm-511/macro.s rename to contrib/relic/src/low/x64-asm-8l/macro.s index 6c966a3a6..af7492df8 100644 --- a/contrib/relic/src/low/x64-asm-511/macro.s +++ b/contrib/relic/src/low/x64-asm-8l/macro.s @@ -32,6 +32,7 @@ * @ingroup fp */ +#if FP_PRIME == 511 #define P0 0x84DD401C8E4AB001 #define P1 0x98707BD8B8D7F1F5 #define P2 0x9BF81D9D036E1774 @@ -41,6 +42,17 @@ #define P6 0x0000031F8F000000 #define P7 0x4000000000156000 #define U0 0xDF085042554AAFFF +#else +#define P0 0xA13D118DB8BFD2AB +#define P1 0xEE63BD076E8D9300 +#define P2 0xCFCB5C6071BAD3D2 +#define P3 0x626E85BF7C18A0F0 +#define P4 0x32EA0103E01090BB +#define P5 0xCB8AC8495D187E8C +#define P6 0xFCEDF2B4F9C0ECF6 +#define P7 0x155556FFFF39CA9B +#define U0 0x6EFA1180A5FE67FD +#endif .text diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_add_low.s b/contrib/relic/src/low/x64-asm-8l/relic_fp_add_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_add_low.s rename to contrib/relic/src/low/x64-asm-8l/relic_fp_add_low.s diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_inv_low.c b/contrib/relic/src/low/x64-asm-8l/relic_fp_inv_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_inv_low.c rename to contrib/relic/src/low/x64-asm-8l/relic_fp_inv_low.c diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_inv_low.s b/contrib/relic/src/low/x64-asm-8l/relic_fp_inv_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_inv_low.s rename to contrib/relic/src/low/x64-asm-8l/relic_fp_inv_low.s diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_mul_low.c b/contrib/relic/src/low/x64-asm-8l/relic_fp_mul_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_mul_low.c rename to contrib/relic/src/low/x64-asm-8l/relic_fp_mul_low.c diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_mul_low.s b/contrib/relic/src/low/x64-asm-8l/relic_fp_mul_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_mul_low.s rename to contrib/relic/src/low/x64-asm-8l/relic_fp_mul_low.s diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_rdc_low.c b/contrib/relic/src/low/x64-asm-8l/relic_fp_rdc_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_rdc_low.c rename to contrib/relic/src/low/x64-asm-8l/relic_fp_rdc_low.c diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_rdc_low.s b/contrib/relic/src/low/x64-asm-8l/relic_fp_rdc_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_rdc_low.s rename to contrib/relic/src/low/x64-asm-8l/relic_fp_rdc_low.s diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_shift_low.c b/contrib/relic/src/low/x64-asm-8l/relic_fp_shift_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_shift_low.c rename to contrib/relic/src/low/x64-asm-8l/relic_fp_shift_low.c diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_shift_low.s b/contrib/relic/src/low/x64-asm-8l/relic_fp_shift_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_shift_low.s rename to contrib/relic/src/low/x64-asm-8l/relic_fp_shift_low.s diff --git a/contrib/relic/src/low/x64-asm-8l/relic_fp_smb_low.c b/contrib/relic/src/low/x64-asm-8l/relic_fp_smb_low.c new file mode 100644 index 000000000..d25200282 --- /dev/null +++ b/contrib/relic/src/low/x64-asm-8l/relic_fp_smb_low.c @@ -0,0 +1,67 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of the low-level inversion functions. + * + * @&version $Id$ + * @ingroup fp + */ + +#include + +#include "relic_fp.h" +#include "relic_fp_low.h" +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int fp_smbm_low(const dig_t *a) { + mpz_t n, p; + rlc_align dig_t t[2 * RLC_FP_DIGS], u[RLC_FP_DIGS]; + int res; + + mpz_init(n); + mpz_init(p); + +#if FP_RDC == MONTY + dv_zero(t + RLC_FP_DIGS, RLC_FP_DIGS); + dv_copy(t, a, RLC_FP_DIGS); + fp_rdcn_low(u, t); +#else + fp_copy(u, a); +#endif + + mpz_import(n, RLC_FP_DIGS, -1, sizeof(dig_t), 0, 0, u); + mpz_import(p, RLC_FP_DIGS, -1, sizeof(dig_t), 0, 0, fp_prime_get()); + + res = mpz_jacobi(n, p); + + mpz_clear(n); + mpz_clear(p); + return res; +} diff --git a/contrib/relic/src/low/x64-asm-511/relic_fp_sqr_low.c b/contrib/relic/src/low/x64-asm-8l/relic_fp_sqr_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-511/relic_fp_sqr_low.c rename to contrib/relic/src/low/x64-asm-8l/relic_fp_sqr_low.c diff --git a/contrib/relic/src/low/x64-asm-nine/CMakeLists.txt b/contrib/relic/src/low/x64-asm-9l/CMakeLists.txt similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/CMakeLists.txt rename to contrib/relic/src/low/x64-asm-9l/CMakeLists.txt diff --git a/contrib/relic/src/low/x64-asm-nine/macro.s b/contrib/relic/src/low/x64-asm-9l/macro.s similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/macro.s rename to contrib/relic/src/low/x64-asm-9l/macro.s diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fp_add_low.s b/contrib/relic/src/low/x64-asm-9l/relic_fp_add_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fp_add_low.s rename to contrib/relic/src/low/x64-asm-9l/relic_fp_add_low.s diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fp_mul_low.c b/contrib/relic/src/low/x64-asm-9l/relic_fp_mul_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fp_mul_low.c rename to contrib/relic/src/low/x64-asm-9l/relic_fp_mul_low.c diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fp_mul_low.s b/contrib/relic/src/low/x64-asm-9l/relic_fp_mul_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fp_mul_low.s rename to contrib/relic/src/low/x64-asm-9l/relic_fp_mul_low.s diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fp_rdc_low.c b/contrib/relic/src/low/x64-asm-9l/relic_fp_rdc_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fp_rdc_low.c rename to contrib/relic/src/low/x64-asm-9l/relic_fp_rdc_low.c diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fp_rdc_low.s b/contrib/relic/src/low/x64-asm-9l/relic_fp_rdc_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fp_rdc_low.s rename to contrib/relic/src/low/x64-asm-9l/relic_fp_rdc_low.s diff --git a/contrib/relic/src/low/x64-asm-9l/relic_fp_smb_low.c b/contrib/relic/src/low/x64-asm-9l/relic_fp_smb_low.c new file mode 100644 index 000000000..d25200282 --- /dev/null +++ b/contrib/relic/src/low/x64-asm-9l/relic_fp_smb_low.c @@ -0,0 +1,67 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of the low-level inversion functions. + * + * @&version $Id$ + * @ingroup fp + */ + +#include + +#include "relic_fp.h" +#include "relic_fp_low.h" +#include "relic_core.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +int fp_smbm_low(const dig_t *a) { + mpz_t n, p; + rlc_align dig_t t[2 * RLC_FP_DIGS], u[RLC_FP_DIGS]; + int res; + + mpz_init(n); + mpz_init(p); + +#if FP_RDC == MONTY + dv_zero(t + RLC_FP_DIGS, RLC_FP_DIGS); + dv_copy(t, a, RLC_FP_DIGS); + fp_rdcn_low(u, t); +#else + fp_copy(u, a); +#endif + + mpz_import(n, RLC_FP_DIGS, -1, sizeof(dig_t), 0, 0, u); + mpz_import(p, RLC_FP_DIGS, -1, sizeof(dig_t), 0, 0, fp_prime_get()); + + res = mpz_jacobi(n, p); + + mpz_clear(n); + mpz_clear(p); + return res; +} diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fp_sqr_low.c b/contrib/relic/src/low/x64-asm-9l/relic_fp_sqr_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fp_sqr_low.c rename to contrib/relic/src/low/x64-asm-9l/relic_fp_sqr_low.c diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fpx_rdc_low.c b/contrib/relic/src/low/x64-asm-9l/relic_fpx_rdc_low.c similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fpx_rdc_low.c rename to contrib/relic/src/low/x64-asm-9l/relic_fpx_rdc_low.c diff --git a/contrib/relic/src/low/x64-asm-nine/relic_fpx_rdc_low.s b/contrib/relic/src/low/x64-asm-9l/relic_fpx_rdc_low.s similarity index 100% rename from contrib/relic/src/low/x64-asm-nine/relic_fpx_rdc_low.s rename to contrib/relic/src/low/x64-asm-9l/relic_fpx_rdc_low.s diff --git a/contrib/relic/src/md/blake2-impl.h b/contrib/relic/src/md/blake2-impl.h index 5ac7a430f..c1df82e0c 100644 --- a/contrib/relic/src/md/blake2-impl.h +++ b/contrib/relic/src/md/blake2-impl.h @@ -1,22 +1,36 @@ /* BLAKE2 reference source code package - reference C implementations - Written in 2012 by Samuel Neves + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . + More information about the BLAKE2 hash function can be found at + https://blake2.net. */ -#pragma once -#ifndef __BLAKE2_IMPL_H__ -#define __BLAKE2_IMPL_H__ +#ifndef BLAKE2_IMPL_H +#define BLAKE2_IMPL_H #include +#include + +#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) + #if defined(_MSC_VER) + #define BLAKE2_INLINE __inline + #elif defined(__GNUC__) + #define BLAKE2_INLINE __inline__ + #else + #define BLAKE2_INLINE + #endif +#else + #define BLAKE2_INLINE inline +#endif -static inline uint32_t load32( const void *src ) +static BLAKE2_INLINE uint32_t load32( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint32_t w; @@ -24,15 +38,14 @@ static inline uint32_t load32( const void *src ) return w; #else const uint8_t *p = ( const uint8_t * )src; - uint32_t w = *p++; - w |= ( uint32_t )( *p++ ) << 8; - w |= ( uint32_t )( *p++ ) << 16; - w |= ( uint32_t )( *p++ ) << 24; - return w; + return (( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8) | + (( uint32_t )( p[2] ) << 16) | + (( uint32_t )( p[3] ) << 24) ; #endif } -static inline uint64_t load64( const void *src ) +static BLAKE2_INLINE uint64_t load64( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint64_t w; @@ -40,97 +53,108 @@ static inline uint64_t load64( const void *src ) return w; #else const uint8_t *p = ( const uint8_t * )src; - uint64_t w = *p++; - w |= ( uint64_t )( *p++ ) << 8; - w |= ( uint64_t )( *p++ ) << 16; - w |= ( uint64_t )( *p++ ) << 24; - w |= ( uint64_t )( *p++ ) << 32; - w |= ( uint64_t )( *p++ ) << 40; - w |= ( uint64_t )( *p++ ) << 48; - w |= ( uint64_t )( *p++ ) << 56; - return w; + return (( uint64_t )( p[0] ) << 0) | + (( uint64_t )( p[1] ) << 8) | + (( uint64_t )( p[2] ) << 16) | + (( uint64_t )( p[3] ) << 24) | + (( uint64_t )( p[4] ) << 32) | + (( uint64_t )( p[5] ) << 40) | + (( uint64_t )( p[6] ) << 48) | + (( uint64_t )( p[7] ) << 56) ; #endif } -static inline void store32( void *dst, uint32_t w ) +static BLAKE2_INLINE uint16_t load16( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); + uint16_t w; + memcpy(&w, src, sizeof w); + return w; #else - uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; + const uint8_t *p = ( const uint8_t * )src; + return ( uint16_t )((( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8)); #endif } -static inline void store64( void *dst, uint64_t w ) +static BLAKE2_INLINE void store16( void *dst, uint16_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; *p++ = ( uint8_t )w; #endif } -static inline uint64_t load48( const void *src ) +static BLAKE2_INLINE void store32( void *dst, uint32_t w ) { - const uint8_t *p = ( const uint8_t * )src; - uint64_t w = *p++; - w |= ( uint64_t )( *p++ ) << 8; - w |= ( uint64_t )( *p++ ) << 16; - w |= ( uint64_t )( *p++ ) << 24; - w |= ( uint64_t )( *p++ ) << 32; - w |= ( uint64_t )( *p++ ) << 40; - return w; +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); +#endif } -static inline void store48( void *dst, uint64_t w ) +static BLAKE2_INLINE void store64( void *dst, uint64_t w ) { +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); + p[4] = (uint8_t)(w >> 32); + p[5] = (uint8_t)(w >> 40); + p[6] = (uint8_t)(w >> 48); + p[7] = (uint8_t)(w >> 56); +#endif } -static inline uint32_t rotl32( const uint32_t w, const unsigned c ) +static BLAKE2_INLINE uint64_t load48( const void *src ) { - return ( w << c ) | ( w >> ( 32 - c ) ); + const uint8_t *p = ( const uint8_t * )src; + return (( uint64_t )( p[0] ) << 0) | + (( uint64_t )( p[1] ) << 8) | + (( uint64_t )( p[2] ) << 16) | + (( uint64_t )( p[3] ) << 24) | + (( uint64_t )( p[4] ) << 32) | + (( uint64_t )( p[5] ) << 40) ; } -static inline uint64_t rotl64( const uint64_t w, const unsigned c ) +static BLAKE2_INLINE void store48( void *dst, uint64_t w ) { - return ( w << c ) | ( w >> ( 64 - c ) ); + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); + p[4] = (uint8_t)(w >> 32); + p[5] = (uint8_t)(w >> 40); } -static inline uint32_t rotr32( const uint32_t w, const unsigned c ) +static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 32 - c ) ); } -static inline uint64_t rotr64( const uint64_t w, const unsigned c ) +static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 64 - c ) ); } /* prevents compiler optimizing out memset() */ -static inline void secure_zero_memory( void *v, size_t n ) +static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) { - volatile uint8_t *p = ( volatile uint8_t * )v; - while( n-- ) *p++ = 0; + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); } #endif - diff --git a/contrib/relic/src/md/blake2.h b/contrib/relic/src/md/blake2.h index 78d806594..ca390305e 100644 --- a/contrib/relic/src/md/blake2.h +++ b/contrib/relic/src/md/blake2.h @@ -1,26 +1,27 @@ /* BLAKE2 reference source code package - reference C implementations - Written in 2012 by Samuel Neves + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . + More information about the BLAKE2 hash function can be found at + https://blake2.net. */ -#pragma once -#ifndef __BLAKE2_H__ -#define __BLAKE2_H__ +#ifndef BLAKE2_H +#define BLAKE2_H #include #include #if defined(_MSC_VER) -#define ALIGNME(x) __declspec(align(x)) +#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) #else -#define ALIGNME(x) __attribute__((aligned(x))) +#define BLAKE2_PACKED(x) x __attribute__((packed)) #endif #if defined(__cplusplus) @@ -45,112 +46,150 @@ extern "C" { BLAKE2B_PERSONALBYTES = 16 }; -#pragma pack(push, 1) - typedef struct __blake2s_param - { - uint8_t digest_length; // 1 - uint8_t key_length; // 2 - uint8_t fanout; // 3 - uint8_t depth; // 4 - uint32_t leaf_length; // 8 - uint8_t node_offset[6];// 14 - uint8_t node_depth; // 15 - uint8_t inner_length; // 16 - // uint8_t reserved[0]; - uint8_t salt[BLAKE2S_SALTBYTES]; // 24 - uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32 - } blake2s_param; - - ALIGNME( 64 ) typedef struct __blake2s_state + typedef struct blake2s_state__ { uint32_t h[8]; uint32_t t[2]; uint32_t f[2]; - uint8_t buf[2 * BLAKE2S_BLOCKBYTES]; + uint8_t buf[BLAKE2S_BLOCKBYTES]; size_t buflen; + size_t outlen; uint8_t last_node; - } blake2s_state ; + } blake2s_state; - typedef struct __blake2b_param - { - uint8_t digest_length; // 1 - uint8_t key_length; // 2 - uint8_t fanout; // 3 - uint8_t depth; // 4 - uint32_t leaf_length; // 8 - uint64_t node_offset; // 16 - uint8_t node_depth; // 17 - uint8_t inner_length; // 18 - uint8_t reserved[14]; // 32 - uint8_t salt[BLAKE2B_SALTBYTES]; // 48 - uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64 - } blake2b_param; - - ALIGNME( 64 ) typedef struct __blake2b_state + typedef struct blake2b_state__ { uint64_t h[8]; uint64_t t[2]; uint64_t f[2]; - uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; size_t buflen; + size_t outlen; uint8_t last_node; } blake2b_state; - typedef struct __blake2sp_state + typedef struct blake2sp_state__ { blake2s_state S[8][1]; blake2s_state R[1]; - uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; - size_t buflen; + uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; + size_t buflen; + size_t outlen; } blake2sp_state; - typedef struct __blake2bp_state + typedef struct blake2bp_state__ { blake2b_state S[4][1]; blake2b_state R[1]; - uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; - size_t buflen; + uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; } blake2bp_state; -#pragma pack(pop) - // Streaming API - int blake2s_init( blake2s_state *S, const uint8_t outlen ); - int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + + BLAKE2_PACKED(struct blake2s_param__ + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint16_t xof_length; /* 14 */ + uint8_t node_depth; /* 15 */ + uint8_t inner_length; /* 16 */ + /* uint8_t reserved[0]; */ + uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ + uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ + }); + + typedef struct blake2s_param__ blake2s_param; + + BLAKE2_PACKED(struct blake2b_param__ + { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint32_t xof_length; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + }); + + typedef struct blake2b_param__ blake2b_param; + + typedef struct blake2xs_state__ + { + blake2s_state S[1]; + blake2s_param P[1]; + } blake2xs_state; + + typedef struct blake2xb_state__ + { + blake2b_state S[1]; + blake2b_param P[1]; + } blake2xb_state; + + /* Padded structs result in a compile-time error */ + enum { + BLAKE2_DUMMY_1 = 1/(int)(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), + BLAKE2_DUMMY_2 = 1/(int)(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) + }; + + /* Streaming API */ + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); - int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ); - int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ); + int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); + int blake2s_final( blake2s_state *S, void *out, size_t outlen ); - int blake2b_init( blake2b_state *S, const uint8_t outlen ); - int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); - int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ); - int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ); + int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); + int blake2b_final( blake2b_state *S, void *out, size_t outlen ); - int blake2sp_init( blake2sp_state *S, const uint8_t outlen ); - int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); - int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen ); - int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen ); + int blake2sp_init( blake2sp_state *S, size_t outlen ); + int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); + int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); - int blake2bp_init( blake2bp_state *S, const uint8_t outlen ); - int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); - int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen ); - int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen ); + int blake2bp_init( blake2bp_state *S, size_t outlen ); + int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); + int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); - // Simple API - int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); - int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + /* Variable output length API */ + int blake2xs_init( blake2xs_state *S, const size_t outlen ); + int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); + int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); + int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); - int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); - int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); + int blake2xb_init( blake2xb_state *S, const size_t outlen ); + int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); + int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); + int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); - static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) - { - return blake2b( out, in, key, outlen, inlen, keylen ); - } + /* Simple API */ + int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); + + /* This is simply an alias for blake2b */ + int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); #if defined(__cplusplus) } #endif #endif - diff --git a/contrib/relic/src/md/blake2s-ref.c b/contrib/relic/src/md/blake2s-ref.c index 9678e79c8..c8b035f62 100644 --- a/contrib/relic/src/md/blake2s-ref.c +++ b/contrib/relic/src/md/blake2s-ref.c @@ -1,14 +1,16 @@ /* BLAKE2 reference source code package - reference C implementations - Written in 2012 by Samuel Neves + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . + More information about the BLAKE2 hash function can be found at + https://blake2.net. */ #include @@ -38,143 +40,79 @@ static const uint8_t blake2s_sigma[10][16] = { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , }; -static inline int blake2s_set_lastnode( blake2s_state *S ) +static void blake2s_set_lastnode( blake2s_state *S ) { - S->f[1] = -1; - return 0; -} - -static inline int blake2s_clear_lastnode( blake2s_state *S ) -{ - S->f[1] = 0; - return 0; + S->f[1] = (uint32_t)-1; } /* Some helper functions, not necessarily useful */ -static inline int blake2s_set_lastblock( blake2s_state *S ) +static int blake2s_is_lastblock( const blake2s_state *S ) { - if( S->last_node ) blake2s_set_lastnode( S ); - - S->f[0] = -1; - return 0; + return S->f[0] != 0; } -static inline int blake2s_clear_lastblock( blake2s_state *S ) +static void blake2s_set_lastblock( blake2s_state *S ) { - if( S->last_node ) blake2s_clear_lastnode( S ); + if( S->last_node ) blake2s_set_lastnode( S ); - S->f[0] = 0; - return 0; + S->f[0] = (uint32_t)-1; } -static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) { S->t[0] += inc; S->t[1] += ( S->t[0] < inc ); - return 0; -} - -// Parameter-related functions -static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) -{ - P->digest_length = digest_length; - return 0; -} - -static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) -{ - P->fanout = fanout; - return 0; -} - -static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) -{ - P->depth = depth; - return 0; -} - -static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) -{ - store32( &P->leaf_length, leaf_length ); - return 0; -} - -static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) -{ - store48( P->node_offset, node_offset ); - return 0; -} - -static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) -{ - P->node_depth = node_depth; - return 0; -} - -static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) -{ - P->inner_length = inner_length; - return 0; } -static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) -{ - memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); - return 0; -} - -static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) -{ - memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); - return 0; -} - -static inline int blake2s_init0( blake2s_state *S ) +static void blake2s_init0( blake2s_state *S ) { + size_t i; memset( S, 0, sizeof( blake2s_state ) ); - for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; - - return 0; + for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; } /* init2 xors IV with input parameter block */ int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) { + const unsigned char *p = ( const unsigned char * )( P ); + size_t i; + blake2s_init0( S ); - const uint32_t *p = ( const uint32_t * )( P ); /* IV XOR ParamBlock */ - for( size_t i = 0; i < 8; ++i ) - S->h[i] ^= load32( &p[i] ); + for( i = 0; i < 8; ++i ) + S->h[i] ^= load32( &p[i * 4] ); + S->outlen = P->digest_length; return 0; } -// Sequential blake2s initialization -int blake2s_init( blake2s_state *S, const uint8_t outlen ) +/* Sequential blake2s initialization */ +int blake2s_init( blake2s_state *S, size_t outlen ) { blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - P->digest_length = outlen; + P->digest_length = (uint8_t)outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); - store48( &P->node_offset, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; - // memset(P->reserved, 0, sizeof(P->reserved) ); + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); } -int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) { blake2s_param P[1]; @@ -182,15 +120,16 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - P->digest_length = outlen; - P->key_length = keylen; + P->digest_length = (uint8_t)outlen; + P->key_length = (uint8_t)keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); - store48( &P->node_offset, 0 ); + store32( &P->node_offset, 0 ); + store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; - // memset(P->reserved, 0, sizeof(P->reserved) ); + /* memset(P->reserved, 0, sizeof(P->reserved) ); */ memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); @@ -206,16 +145,43 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c return 0; } -static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2s_sigma[r][2*i+0]]; \ + d = rotr32(d ^ a, 16); \ + c = c + d; \ + b = rotr32(b ^ c, 12); \ + a = a + b + m[blake2s_sigma[r][2*i+1]]; \ + d = rotr32(d ^ a, 8); \ + c = c + d; \ + b = rotr32(b ^ c, 7); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) { uint32_t m[16]; uint32_t v[16]; + size_t i; - for( size_t i = 0; i < 16; ++i ) - m[i] = load32( block + i * sizeof( m[i] ) ); + for( i = 0; i < 16; ++i ) { + m[i] = load32( in + i * sizeof( m[i] ) ); + } - for( size_t i = 0; i < 8; ++i ) + for( i = 0; i < 8; ++i ) { v[i] = S->h[i]; + } v[ 8] = blake2s_IV[0]; v[ 9] = blake2s_IV[1]; @@ -225,28 +191,7 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK v[13] = S->t[1] ^ blake2s_IV[5]; v[14] = S->f[0] ^ blake2s_IV[6]; v[15] = S->f[1] ^ blake2s_IV[7]; -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2s_sigma[r][2*i+0]]; \ - d = rotr32(d ^ a, 16); \ - c = c + d; \ - b = rotr32(b ^ c, 12); \ - a = a + b + m[blake2s_sigma[r][2*i+1]]; \ - d = rotr32(d ^ a, 8); \ - c = c + d; \ - b = rotr32(b ^ c, 7); \ - } while(0) -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) + ROUND( 0 ); ROUND( 1 ); ROUND( 2 ); @@ -258,82 +203,79 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK ROUND( 8 ); ROUND( 9 ); - for( size_t i = 0; i < 8; ++i ) + for( i = 0; i < 8; ++i ) { S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} #undef G #undef ROUND - return 0; -} - -int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) +int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) { - while( inlen > 0 ) + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) { size_t left = S->buflen; - size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; - + size_t fill = BLAKE2S_BLOCKBYTES - left; if( inlen > fill ) { - memcpy( S->buf + left, in, fill ); // Fill buffer - S->buflen += fill; + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); // Compress - memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left - S->buflen -= BLAKE2S_BLOCKBYTES; - in += fill; - inlen -= fill; - } - else // inlen <= fill - { - memcpy( S->buf + left, in, inlen ); - S->buflen += inlen; // Be lazy, do not compress - in += inlen; - inlen -= inlen; + blake2s_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2S_BLOCKBYTES) { + blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); + blake2s_compress( S, in ); + in += BLAKE2S_BLOCKBYTES; + inlen -= BLAKE2S_BLOCKBYTES; + } } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; } - return 0; } -int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) +int blake2s_final( blake2s_state *S, void *out, size_t outlen ) { uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; + size_t i; - if( outlen > BLAKE2S_OUTBYTES ) + if( out == NULL || outlen < S->outlen ) return -1; - if( S->buflen > BLAKE2S_BLOCKBYTES ) - { - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); - S->buflen -= BLAKE2S_BLOCKBYTES; - memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); - } + if( blake2s_is_lastblock( S ) ) + return -1; blake2s_increment_counter( S, ( uint32_t )S->buflen ); blake2s_set_lastblock( S ); - memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ + memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ blake2s_compress( S, S->buf ); - for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - + memcpy( out, buffer, outlen ); + secure_zero_memory(buffer, sizeof(buffer)); return 0; } -int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2s_state S[1]; /* Verify parameters */ - if ( NULL == in ) return -1; + if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; - if ( NULL == key ) keylen = 0; /* Fail here instead if keylen != 0 and key == NULL? */ + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; if( keylen > 0 ) { @@ -349,35 +291,77 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen return 0; } +#if defined(SUPERCOP) +int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) +{ + return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); +} +#endif + #if defined(BLAKE2S_SELFTEST) #include #include "blake2-kat.h" -int main( int argc, char **argv ) +int main( void ) { uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; + uint8_t buf[BLAKE2_KAT_LENGTH]; + size_t i, step; - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) + for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i ) + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; - for( size_t i = 0; i < KAT_LENGTH; ++i ) + /* Test simple API */ + for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES]; - blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ); + blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) { - puts( "error" ); - return -1; + goto fail; + } + } + + /* Test streaming API */ + for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { + for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { + uint8_t hash[BLAKE2S_OUTBYTES]; + blake2s_state S; + uint8_t * p = buf; + size_t mlen = i; + int err = 0; + + if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { + goto fail; + } + + while (mlen >= step) { + if ( (err = blake2s_update(&S, p, step)) < 0 ) { + goto fail; + } + mlen -= step; + p += step; + } + if ( (err = blake2s_update(&S, p, mlen)) < 0) { + goto fail; + } + if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { + goto fail; + } + + if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { + goto fail; + } } } puts( "ok" ); return 0; +fail: + puts("error"); + return -1; } #endif - - diff --git a/contrib/relic/src/md/relic_md_blake2s.c b/contrib/relic/src/md/relic_md_blake2s.c index 55ea9ff48..cf0b79b54 100644 --- a/contrib/relic/src/md/relic_md_blake2s.c +++ b/contrib/relic/src/md/relic_md_blake2s.c @@ -45,7 +45,7 @@ void md_map_b2s160(uint8_t *hash, const uint8_t *msg, int len) { memset(hash, 0, RLC_MD_LEN_B2S160); - blake2s(hash, msg, NULL, RLC_MD_LEN_B2S160, len, 0); + blake2s(hash, RLC_MD_LEN_B2S160, msg, len, NULL, 0); } #endif @@ -54,7 +54,7 @@ void md_map_b2s160(uint8_t *hash, const uint8_t *msg, int len) { void md_map_b2s256(uint8_t *hash, const uint8_t *msg, int len) { memset(hash, 0, RLC_MD_LEN_B2S256); - blake2s(hash, msg, NULL, RLC_MD_LEN_B2S256, len, 0); + blake2s(hash, RLC_MD_LEN_B2S256, msg, len, NULL, 0); } #endif diff --git a/contrib/relic/src/md/relic_md_hmac.c b/contrib/relic/src/md/relic_md_hmac.c index 712581161..00b7e63b5 100644 --- a/contrib/relic/src/md/relic_md_hmac.c +++ b/contrib/relic/src/md/relic_md_hmac.c @@ -42,7 +42,7 @@ void md_hmac(uint8_t *mac, const uint8_t *in, int in_len, const uint8_t *key, int key_len) { -#if MD_MAP == SH224 || MD_MAP == SH256 || MD_MAP == BLAKE2S_160 || MD_MAP == BLAKE2S_256 +#if MD_MAP == SH224 || MD_MAP == SH256 || MD_MAP == B2S160 || MD_MAP == B2S256 #define block_size 64 #elif MD_MAP == SH384 || MD_MAP == SH512 #define block_size 128 diff --git a/contrib/relic/src/pc/relic_pc_exp.c b/contrib/relic/src/pc/relic_pc_exp.c index e2fff2328..38e994455 100644 --- a/contrib/relic/src/pc/relic_pc_exp.c +++ b/contrib/relic/src/pc/relic_pc_exp.c @@ -41,6 +41,14 @@ void g1_mul(g1_t c, g1_t a, bn_t b) { bn_null(n); bn_null(_b); + if (bn_bits(b) <= RLC_DIG) { + g1_mul_dig(c, a, b->dp[0]); + if (bn_sign(b) == RLC_NEG) { + g1_neg(c, c); + } + return; + } + RLC_TRY { bn_new(n); bn_new(_b); @@ -85,6 +93,14 @@ void g2_mul(g2_t c, g2_t a, bn_t b) { bn_null(n); bn_null(_b); + if (bn_bits(b) <= RLC_DIG) { + g2_mul_dig(c, a, b->dp[0]); + if (bn_sign(b) == RLC_NEG) { + g2_neg(c, c); + } + return; + } + RLC_TRY { bn_new(n); bn_new(_b); @@ -129,6 +145,14 @@ void gt_exp(gt_t c, gt_t a, bn_t b) { bn_null(n); bn_null(_b); + if (bn_bits(b) <= RLC_DIG) { + gt_exp_dig(c, a, b->dp[0]); + if (bn_sign(b) == RLC_NEG) { + gt_inv(c, c); + } + return; + } + RLC_TRY { bn_new(n); bn_new(_b); @@ -145,6 +169,37 @@ void gt_exp(gt_t c, gt_t a, bn_t b) { } } +void gt_exp_dig(gt_t c, gt_t a, dig_t b) { + gt_t t; + + if (b == 0) { + gt_set_unity(c); + return; + } + + gt_null(t); + + RLC_TRY { + gt_new(t); + + gt_copy(t, a); + for (int i = util_bits_dig(b) - 2; i >= 0; i--) { + gt_sqr(t, t); + if (b & ((dig_t)1 << i)) { + gt_mul(t, t, a); + } + } + + gt_copy(c, t); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + gt_free(t); + } +} + void gt_exp_sim(gt_t e, gt_t a, bn_t b, gt_t c, bn_t d) { bn_t n, _b, _d; diff --git a/contrib/relic/src/pc/relic_pc_util.c b/contrib/relic/src/pc/relic_pc_util.c index af2af3faf..bfd4905e0 100644 --- a/contrib/relic/src/pc/relic_pc_util.c +++ b/contrib/relic/src/pc/relic_pc_util.c @@ -50,39 +50,24 @@ void gt_rand(gt_t a) { gt_rand_imp(a); #if FP_PRIME < 1536 +#if FP_PRIME == 509 + pp_exp_k24(a, a); +#else pp_exp_k12(a, a); +#endif #else pp_exp_k2(a, a); #endif } void gt_get_gen(gt_t g) { - g1_t g1; - g2_t g2; - - g1_null(g1); - g2_null(g2); - - RLC_TRY { - g1_new(g1); - g2_new(g2); - - g1_get_gen(g1); - g2_get_gen(g2); - - pc_map(g, g1, g2); - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - g1_free(g1); - g2_free(g2); - } + gt_copy(g, core_get()->gt_g); } int g1_is_valid(g1_t a) { bn_t n; g1_t t, u, v; - int r; + int r = 0; if (g1_is_infty(a)) { return 0; @@ -102,45 +87,38 @@ int g1_is_valid(g1_t a) { ep_curve_get_cof(n); if (bn_cmp_dig(n, 1) == RLC_EQ) { /* If curve has prime order, simpler to check if point on curve. */ - r = ep_on_curve(a); + r = g1_on_curve(a); } else { switch (ep_curve_is_pairf()) { /* Formulas from "Faster Subgroup Checks for BLS12-381" by Bowe. - * https://eprint.iacr.org/2019/814.pdf */ + * https://eprint.iacr.org/2019/814.pdf, together with tweaks + * by Mike Scott. */ case EP_B12: - /* Check [(z^2−1)](2\psi(P)-P-\psi^2(P)) == [3]\psi^2(P). */ - ep_psi(v, a); - ep_dbl(u, v); - ep_psi(v, v); - ep_sub(u, u, a); - ep_sub(u, u, v); + /* Check [(z^2−1)](\psi(P)+P) == -P.*/ fp_prime_get_par(n); bn_sqr(n, n); - ep_copy(t, u); + bn_sub_dig(n, n, 1); + ep_psi(t, a); + ep_add(t, t, a); + ep_copy(u, t); for (int i = bn_bits(n) - 2; i >= 0; i--) { - ep_dbl(t, t); + g1_dbl(u, u); if (bn_get_bit(n, i)) { - ep_add(t, t, u); + g1_add(u, u, t); } } - ep_sub(t, t, u); - ep_dbl(u, v); - ep_add(u, u, v); - r = ep_on_curve(t) && (ep_cmp(t, u) == RLC_EQ); + g1_neg(v, a); + r = g1_on_curve(a) && (g1_cmp(v, u) == RLC_EQ); break; default: pc_get_ord(n); bn_sub_dig(n, n, 1); /* Otherwise, check order explicitly. */ - g1_copy(u, a); - for (int i = bn_bits(n) - 2; i >= 0; i--) { - g1_dbl(u, u); - if (bn_get_bit(n, i)) { - g1_add(u, u, a); - } - } + /* We use fast scalar multiplication methods here, because + * they should work only in the correct subgroup. */ + g1_mul(u, a, n); g1_neg(u, u); - r = ep_on_curve(a) && (g1_cmp(u, a) == RLC_EQ); + r = g1_on_curve(a) && (g1_cmp(u, a) == RLC_EQ); break; } } @@ -169,7 +147,7 @@ int g2_is_valid(g2_t a) { bn_t p, n; g2_t u, v; - int r; + int r = 0; bn_null(n); bn_null(p); @@ -194,48 +172,54 @@ int g2_is_valid(g2_t a) { /* Compute trace t = p - n + 1. */ bn_sub(n, p, n); bn_add_dig(n, n, 1); - /* Compute u = a^t. */ g2_mul(u, a, n); + if (bn_sign(n) == RLC_NEG) { + g2_neg(u, u); + } /* Compute v = a^(p + 1). */ - ep2_frb(v, a, 1); + g2_frb(v, a, 1); g2_add(v, v, a); /* Check if a^(p + 1) = a^t. */ - r = ep2_on_curve(a) && (g2_cmp(u, v) == RLC_EQ); + r = g2_on_curve(a) && (g2_cmp(u, v) == RLC_EQ); } else { switch (ep_curve_is_pairf()) { /* Formulas from "Faster Subgroup Checks for BLS12-381" by Bowe. * https://eprint.iacr.org/2019/814.pdf */ case EP_B12: +#if FP_PRIME == 383 + /* Since p mod n = r, we can check instead that + * psi^4(P) + P == \psi^2(P). */ + ep2_frb(u, a, 4); + ep2_add(u, u, a); + ep2_frb(v, a, 2); +#else /* Check [z]psi^3(P) + P == \psi^2(P). */ fp_prime_get_par(n); - ep2_copy(u, a); + g2_copy(u, a); for (int i = bn_bits(n) - 2; i >= 0; i--) { - ep2_dbl(u, u); + g2_dbl(u, u); if (bn_get_bit(n, i)) { - ep2_add(u, u, a); + g2_add(u, u, a); } } if (bn_sign(n) == RLC_NEG) { - ep2_neg(u, u); + g2_neg(u, u); } - ep2_frb(u, u, 3); - ep2_frb(v, a, 2); - ep2_add(u, u, a); - r = ep2_on_curve(a) && (g2_cmp(u, v) == RLC_EQ); + g2_frb(u, u, 3); + g2_frb(v, a, 2); + g2_add(u, u, a); +#endif + r = g2_on_curve(a) && (g2_cmp(u, v) == RLC_EQ); break; default: pc_get_ord(n); bn_sub_dig(n, n, 1); /* Otherwise, check order explicitly. */ - g2_copy(u, a); - for (int i = bn_bits(n) - 2; i >= 0; i--) { - g2_dbl(u, u); - if (bn_get_bit(n, i)) { - g2_add(u, u, a); - } - } + /* We use fast scalar multiplication methods here, because + * they should work only in the correct order. */ + g2_mul(u, a, n); g2_neg(u, u); - r = ep2_on_curve(a) && (g2_cmp(u, a) == RLC_EQ); + r = g2_on_curve(a) && (g2_cmp(u, a) == RLC_EQ); break; } } @@ -252,10 +236,13 @@ int g2_is_valid(g2_t a) { #endif } +#define GLS_MEMBER + int gt_is_valid(gt_t a) { bn_t p, n; gt_t u, v; - int r; + int l, r = 0; + const int *b; if (gt_is_unity(a)) { return 0; @@ -275,43 +262,102 @@ int gt_is_valid(gt_t a) { pc_get_ord(n); ep_curve_get_cof(p); + /* For a BN curve, we can use the fast test from + * Unbalancing Pairing-Based Key Exchange Protocols by Scott. + * https://eprint.iacr.org/2013/688.pdf */ if (bn_cmp_dig(p, 1) == RLC_EQ) { dv_copy(p->dp, fp_prime_get(), RLC_FP_DIGS); p->used = RLC_FP_DIGS; p->sign = RLC_POS; - /* Compute trace t = p - n + 1. */ - bn_sub(n, p, n); - bn_add_dig(n, n, 1); - /* Compute u = a^t. */ - gt_exp(u, a, n); + if (ep_curve_is_pairf() == EP_BN) { + /* Compute trace t = p - n + 1, and compute a^t. */ + fp_prime_get_par(n); + b = fp_prime_get_par_sps(&l); + fp12_exp_cyc_sps((void *)v, (void *)a, b, l, RLC_POS); + fp12_exp_cyc_sps((void *)u, (void *)v, b, l, RLC_POS); + gt_sqr(v, u); + gt_sqr(u, v); + gt_mul(u, u, v); + } else { + /* Compute trace t = p - n + 1. */ + bn_sub(n, p, n); + /* Compute u = a^t. */ + gt_exp(u, a, n); + } /* Compute v = a^(p + 1). */ gt_frb(v, a, 1); - gt_mul(v, v, a); /* Check if a^(p + 1) = a^t. */ - r = (gt_cmp(u, v) == RLC_EQ); + r = fp12_test_cyc((void *)a) && (gt_cmp(u, v) == RLC_EQ); } else { + fp_prime_get_par(n); + b = fp_prime_get_par_sps(&l); switch (ep_curve_is_pairf()) { /* Formulas from "Faster Subgroup Checks for BLS12-381" by Bowe. * https://eprint.iacr.org/2019/814.pdf */ case EP_B12: - /* Check [z]psi^3(P) + P == \psi^2(P). */ - fp_prime_get_par(n); - gt_exp(u, a, n); - gt_frb(u, u, 3); - gt_frb(v, a, 2); +#if FP_PRIME == 383 + /* GT-strong, so test for cyclotomic only. */ + r = 1; +#else +#ifdef GLS_MEMBER + /* The 4-GLS recoding of the exponent gives this. */ + fp12_exp_cyc_sps((void *)u, (void *)a, b, l, RLC_POS); + gt_inv(u, u); + gt_mul(u, u, a); + gt_inv(u, u); + gt_frb(u, u, 2); + gt_frb(v, u, 1); + gt_inv(v, v); + gt_mul(u, u, v); + gt_inv(u, u); + r = (gt_cmp(u, a) == RLC_EQ); +#else + gt_frb(u, a, 1); + fp12_exp_cyc_sps((void *)v, (void *)a, b, l, bn_sign(n)); + r = (gt_cmp(u, v) == RLC_EQ); + fp12_exp_cyc_sps((void *)u, (void *)v, b, l, bn_sign(n)); + gt_mul(u, u, a); + gt_sqr(v, v); + r &= (gt_cmp(u, v) != RLC_EQ); +#endif +#endif + r &= fp12_test_cyc((void *)a); + break; +#if FP_PRIME == 509 + case EP_B24: +#ifdef GLS_MEMBER + /* The 8-GLS recoding of the exponent gives this. */ + fp24_exp_cyc_sps((void *)u, (void *)a, b, l, bn_sign(n)); gt_mul(u, u, a); + gt_inv(u, u); + gt_frb(u, u, 4); + gt_frb(v, u, 1); + gt_inv(v, v); + gt_mul(u, u, v); + gt_frb(v, v, 1); + gt_inv(v, v); + gt_mul(u, u, v); + gt_frb(v, v, 1); + gt_inv(v, v); + gt_mul(u, u, v); + gt_inv(u, u); + r = (gt_cmp(u, a) == RLC_EQ); +#else + gt_frb(u, a, 1); + fp24_exp_cyc_sps((void *)v, (void *)a, b, l, bn_sign(n)); r = (gt_cmp(u, v) == RLC_EQ); + fp24_exp_cyc_sps((void *)u, (void *)v, b, l, bn_sign(n)); + gt_mul(u, u, a); + gt_sqr(v, v); + r &= (gt_cmp(u, v) != RLC_EQ); +#endif + r = fp24_test_cyc((void *)a); break; +#endif default: /* Common case. */ bn_sub_dig(n, n, 1); - gt_copy(u, a); - for (int i = bn_bits(n) - 2; i >= 0; i--) { - gt_sqr(u, u); - if (bn_get_bit(n, i)) { - gt_mul(u, u, a); - } - } + gt_exp(u, a, n); gt_inv(u, u); r = (gt_cmp(u, a) == RLC_EQ); break; diff --git a/contrib/relic/src/pp/relic_pp_add_k12.c b/contrib/relic/src/pp/relic_pp_add_k12.c index 2123388af..295e123a9 100644 --- a/contrib/relic/src/pp/relic_pp_add_k12.c +++ b/contrib/relic/src/pp/relic_pp_add_k12.c @@ -124,9 +124,9 @@ void pp_add_k12_projc_basic(fp12_t l, ep2_t r, ep2_t q, ep_t p) { } /* l10 = - (A * xp). */ - fp_mul(l[one][zero][0], t1[0], p->x); - fp_mul(l[one][zero][1], t1[1], p->x); - fp2_neg(l[one][zero], l[one][zero]); + fp_neg(t4[0], p->x); + fp_mul(l[one][zero][0], t1[0], t4[0]); + fp_mul(l[one][zero][1], t1[1], t4[0]); /* t4 = B * x2. */ fp2_mul(t4, q->x, t1); @@ -222,9 +222,9 @@ void pp_add_k12_projc_lazyr(fp12_t l, ep2_t r, ep2_t q, ep_t p) { zero ^= 1; } - fp_mul(l[one][zero][0], t1[0], p->x); - fp_mul(l[one][zero][1], t1[1], p->x); - fp2_neg(l[one][zero], l[one][zero]); + fp_neg(t3[0], p->x); + fp_mul(l[one][zero][0], t1[0], t3[0]); + fp_mul(l[one][zero][1], t1[1], t3[0]); #ifdef RLC_FP_ROOM fp2_mulc_low(u0, q->x, t1); diff --git a/contrib/relic/src/pp/relic_pp_add_k24.c b/contrib/relic/src/pp/relic_pp_add_k24.c new file mode 100644 index 000000000..f64d499fe --- /dev/null +++ b/contrib/relic/src/pp/relic_pp_add_k24.c @@ -0,0 +1,160 @@ +/* + * RELIC is an Efficient LIbrar->y for Cr->yptography + * Copyright (c) 2021 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of pairing computation for curves with embedding degree 24. + * + * @ingroup pp + */ + +#include "relic_core.h" +#include "relic_pp.h" +#include "relic_util.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +#if EP_ADD == BASIC || !defined(STRIP) + +void pp_add_k24_basic(fp24_t l, ep4_t r, ep4_t q, ep_t p) { + fp4_t s; + ep4_t t; + + fp4_null(s); + ep4_null(t); + + RLC_TRY { + fp4_new(s); + ep4_new(t); + + ep4_copy(t, r); + ep4_add_slp_basic(r, s, r, q); + + fp_mul(l[1][1][0][0], s[0][0], p->x); + fp_mul(l[1][1][0][1], s[0][1], p->x); + fp_mul(l[1][1][1][0], s[1][0], p->x); + fp_mul(l[1][1][1][1], s[1][1], p->x); + + fp4_mul(l[0][0], s, t->x); + fp4_sub(l[0][0], t->y, l[0][0]); + fp4_mul_art(l[0][0], l[0][0]); + + fp_neg(l[0][1][0][0], p->y); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(s); + ep4_free(t); + } +} + +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + +void pp_add_k24_projc(fp24_t l, ep4_t r, ep4_t q, ep_t p) { + fp4_t t0, t1, t2, t3, t4; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + + /* B = t0 = x1 - x2 * z1. */ + fp4_mul(t0, r->z, q->x); + fp4_sub(t0, r->x, t0); + /* A = t1 = y1 - y2 * z1. */ + fp4_mul(t1, r->z, q->y); + fp4_sub(t1, r->y, t1); + + /* D = B^2. */ + fp4_sqr(t2, t0); + /* G = x1 * D. */ + fp4_mul(r->x, r->x, t2); + /* E = B^3. */ + fp4_mul(t2, t2, t0); + /* C = A^2. */ + fp4_sqr(t3, t1); + /* F = E + z1 * C. */ + fp4_mul(t3, t3, r->z); + fp4_add(t3, t2, t3); + + /* l10 = - (A * xp). */ + fp_neg(t4[0][0], p->x); + fp_mul(l[1][1][0][0], t1[0][0], t4[0][0]); + fp_mul(l[1][1][0][1], t1[0][1], t4[0][0]); + fp_mul(l[1][1][1][0], t1[1][0], t4[0][0]); + fp_mul(l[1][1][1][1], t1[1][1], t4[0][0]); + + /* t4 = B * x2. */ + fp4_mul(t4, q->x, t1); + + /* H = E + F - 2 * G. */ + fp4_sub(t3, t3, r->x); + fp4_sub(t3, t3, r->x); + /* y3 = A * (G - H) - y1 * E. */ + fp4_sub(r->x, r->x, t3); + fp4_mul(t1, t1, r->x); + fp4_mul(r->y, t2, r->y); + fp4_sub(r->y, t1, r->y); + /* x3 = B * H. */ + fp4_mul(r->x, t0, t3); + /* z3 = z1 * E. */ + fp4_mul(r->z, r->z, t2); + + /* l11 = J = B * x2 - A * y2. */ + fp4_mul(t2, q->y, t0); + fp4_sub(l[0][0], t4, t2); + fp4_mul_art(l[0][0], l[0][0]); + + /* l00 = B * yp. */ + fp_mul(l[0][1][0][0], p->y, t0[0][0]); + fp_mul(l[0][1][0][1], p->y, t0[0][1]); + fp_mul(l[0][1][1][0], p->y, t0[1][0]); + fp_mul(l[0][1][1][1], p->y, t0[1][1]); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + } +} + +#endif diff --git a/contrib/relic/src/pp/relic_pp_add_k48.c b/contrib/relic/src/pp/relic_pp_add_k48.c index 0c96b61d0..225612b74 100644 --- a/contrib/relic/src/pp/relic_pp_add_k48.c +++ b/contrib/relic/src/pp/relic_pp_add_k48.c @@ -186,15 +186,15 @@ void pp_add_k48_projc(fp48_t l, fp8_t rx, fp8_t ry, fp8_t rz, fp8_t qx, fp8_add(t3, t2, t3); /* l10 = - (A * xp). */ - fp_mul(l[0][1][0][0][0], p->x, t1[0][0][0]); - fp_mul(l[0][1][0][0][1], p->x, t1[0][0][1]); - fp_mul(l[0][1][0][1][0], p->x, t1[0][1][0]); - fp_mul(l[0][1][0][1][1], p->x, t1[0][1][1]); - fp_mul(l[0][1][1][0][0], p->x, t1[1][0][0]); - fp_mul(l[0][1][1][0][1], p->x, t1[1][0][1]); - fp_mul(l[0][1][1][1][0], p->x, t1[1][1][0]); - fp_mul(l[0][1][1][1][1], p->x, t1[1][1][1]); - fp8_neg(l[0][1], l[0][1]); + fp_neg(t4[0][0][0], p->x); + fp_mul(l[0][1][0][0][0], t1[0][0][0], t4[0][0][0]); + fp_mul(l[0][1][0][0][1], t1[0][0][1], t4[0][0][0]); + fp_mul(l[0][1][0][1][0], t1[0][1][0], t4[0][0][0]); + fp_mul(l[0][1][0][1][1], t1[0][1][1], t4[0][0][0]); + fp_mul(l[0][1][1][0][0], t1[1][0][0], t4[0][0][0]); + fp_mul(l[0][1][1][0][1], t1[1][0][1], t4[0][0][0]); + fp_mul(l[0][1][1][1][0], t1[1][1][0], t4[0][0][0]); + fp_mul(l[0][1][1][1][1], t1[1][1][1], t4[0][0][0]); /* t4 = B * x2. */ fp8_mul(t4, qx, t1); diff --git a/contrib/relic/src/pp/relic_pp_add_k54.c b/contrib/relic/src/pp/relic_pp_add_k54.c index 841c9b0d5..bdbdcde90 100644 --- a/contrib/relic/src/pp/relic_pp_add_k54.c +++ b/contrib/relic/src/pp/relic_pp_add_k54.c @@ -187,16 +187,16 @@ void pp_add_k54_projc(fp54_t l, fp9_t rx, fp9_t ry, fp9_t rz, fp9_t qx, fp9_add(t3, t2, t3); /* l10 = - (A * xp). */ - fp_mul(l[2][0][0][0], p->x, t1[0][0]); - fp_mul(l[2][0][0][1], p->x, t1[0][1]); - fp_mul(l[2][0][0][2], p->x, t1[0][2]); - fp_mul(l[2][0][1][0], p->x, t1[1][0]); - fp_mul(l[2][0][1][1], p->x, t1[1][1]); - fp_mul(l[2][0][1][2], p->x, t1[1][2]); - fp_mul(l[2][0][2][0], p->x, t1[2][0]); - fp_mul(l[2][0][2][1], p->x, t1[2][1]); - fp_mul(l[2][0][2][2], p->x, t1[2][2]); - fp9_neg(l[2][0], l[2][0]); + fp_neg(t4[0][0], p->x); + fp_mul(l[2][0][0][0], t1[0][0], t4[0][0]); + fp_mul(l[2][0][0][1], t1[0][1], t4[0][0]); + fp_mul(l[2][0][0][2], t1[0][2], t4[0][0]); + fp_mul(l[2][0][1][0], t1[1][0], t4[0][0]); + fp_mul(l[2][0][1][1], t1[1][1], t4[0][0]); + fp_mul(l[2][0][1][2], t1[1][2], t4[0][0]); + fp_mul(l[2][0][2][0], t1[2][0], t4[0][0]); + fp_mul(l[2][0][2][1], t1[2][1], t4[0][0]); + fp_mul(l[2][0][2][2], t1[2][2], t4[0][0]); /* t4 = B * x2. */ fp9_mul(t4, qx, t1); diff --git a/contrib/relic/src/pp/relic_pp_dbl_k12.c b/contrib/relic/src/pp/relic_pp_dbl_k12.c index f6bcf48ea..743eb365a 100644 --- a/contrib/relic/src/pp/relic_pp_dbl_k12.c +++ b/contrib/relic/src/pp/relic_pp_dbl_k12.c @@ -54,7 +54,6 @@ void pp_dbl_k12_basic(fp12_t l, ep2_t r, ep2_t q, ep_t p) { ep2_new(t); ep2_copy(t, q); ep2_dbl_slp_basic(r, s, q); - fp12_zero(l); if (ep2_curve_is_twist() == RLC_EP_MTYPE) { one ^= 1; diff --git a/contrib/relic/src/pp/relic_pp_dbl_k24.c b/contrib/relic/src/pp/relic_pp_dbl_k24.c new file mode 100644 index 000000000..3935047ae --- /dev/null +++ b/contrib/relic/src/pp/relic_pp_dbl_k24.c @@ -0,0 +1,177 @@ +/* + * RELIC is an Efficient LIbrar->y for Cr->yptography + * Copyright (c) 2019 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of pairing computation for curves with embedding degree 24. + * + * @ingroup pp + */ + +#include "relic_core.h" +#include "relic_pp.h" +#include "relic_util.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +#if EP_ADD == PROJC || !defined(STRIP) + +void pp_dbl_k24_basic(fp24_t l, ep4_t r, ep4_t q, ep_t p) { + fp4_t s; + ep4_t t; + + fp4_null(s); + ep4_null(t); + + RLC_TRY { + fp4_new(s); + ep4_new(t); + ep4_copy(t, q); + ep4_dbl_slp_basic(r, s, q); + fp24_zero(l); + + fp_mul(l[1][1][0][0], s[0][0], p->x); + fp_mul(l[1][1][0][1], s[0][1], p->x); + fp_mul(l[1][1][1][0], s[1][0], p->x); + fp_mul(l[1][1][1][1], s[1][1], p->x); + + fp4_mul(l[0][0], s, t->x); + fp4_sub(l[0][0], t->y, l[0][0]); + fp4_mul_art(l[0][0], l[0][0]); + + fp_copy(l[0][1][0][0], p->y); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp2_free(s); + ep4_free(t); + } +} + +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + +void pp_dbl_k24_projc(fp24_t l, ep4_t r, ep4_t q, ep_t p) { + fp4_t t0, t1, t2, t3, t4, t5, t6; + + fp4_null(t0); + fp4_null(t1); + fp4_null(t2); + fp4_null(t3); + fp4_null(t4); + fp4_null(t5); + fp4_null(t6); + + RLC_TRY { + fp4_new(t0); + fp4_new(t1); + fp4_new(t2); + fp4_new(t3); + fp4_new(t4); + fp4_new(t5); + fp4_new(t6); + + /* A = x1^2. */ + fp4_sqr(t0, q->x); + /* B = y1^2. */ + fp4_sqr(t1, q->y); + /* C = z1^2. */ + fp4_sqr(t2, q->z); + /* D = 3bC, general b. */ + fp4_dbl(t3, t2); + fp4_add(t3, t3, t2); + ep4_curve_get_b(t4); + fp4_mul(t3, t3, t4); + + /* E = (x1 + y1)^2 - A - B. */ + fp4_add(t4, q->x, q->y); + fp4_sqr(t4, t4); + fp4_sub(t4, t4, t0); + fp4_sub(t4, t4, t1); + + /* F = (y1 + z1)^2 - B - C. */ + fp4_add(t5, q->y, q->z); + fp4_sqr(t5, t5); + fp4_sub(t5, t5, t1); + fp4_sub(t5, t5, t2); + + /* G = 3D. */ + fp4_dbl(t6, t3); + fp4_add(t6, t6, t3); + + /* x3 = E * (B - G). */ + fp4_sub(r->x, t1, t6); + fp4_mul(r->x, r->x, t4); + + /* y3 = (B + G)^2 -12D^2. */ + fp4_add(t6, t6, t1); + fp4_sqr(t6, t6); + fp4_sqr(t2, t3); + fp4_dbl(r->y, t2); + fp4_dbl(t2, r->y); + fp4_dbl(r->y, t2); + fp4_add(r->y, r->y, t2); + fp4_sub(r->y, t6, r->y); + + /* z3 = 4B * F. */ + fp4_dbl(r->z, t1); + fp4_dbl(r->z, r->z); + fp4_mul(r->z, r->z, t5); + + /* l11 = D - B. */ + fp4_sub(l[0][0], t3, t1); + fp4_mul_art(l[0][0], l[0][0]); + + /* l10 = (3 * xp) * A. */ + fp_mul(l[1][1][0][0], p->x, t0[0][0]); + fp_mul(l[1][1][0][1], p->x, t0[0][1]); + fp_mul(l[1][1][1][0], p->x, t0[1][0]); + fp_mul(l[1][1][1][1], p->x, t0[1][1]); + + /* l00 = F * (-yp). */ + fp_mul(l[0][1][0][0], p->y, t5[0][0]); + fp_mul(l[0][1][0][1], p->y, t5[0][1]); + fp_mul(l[0][1][1][0], p->y, t5[1][0]); + fp_mul(l[0][1][1][1], p->y, t5[1][1]); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp4_free(t0); + fp4_free(t1); + fp4_free(t2); + fp4_free(t3); + fp4_free(t4); + fp4_free(t5); + fp4_free(t6); + } +} + +#endif diff --git a/contrib/relic/src/pp/relic_pp_exp_k24.c b/contrib/relic/src/pp/relic_pp_exp_k24.c new file mode 100644 index 000000000..7f075d680 --- /dev/null +++ b/contrib/relic/src/pp/relic_pp_exp_k24.c @@ -0,0 +1,107 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2019 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of the final exponentiation for curves of embedding degree 24. + * + * @ingroup pp + */ + +#include "relic_core.h" +#include "relic_pp.h" +#include "relic_util.h" + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +void pp_exp_k24(fp24_t c, fp24_t a) { + fp24_t t[8]; + const int *b; + bn_t x; + int l; + + bn_null(x); + + RLC_TRY { + bn_new(x); + for (int i = 0; i < 8; i++) { + fp24_null(t[i]); + fp24_new(t[i]); + } + + fp_prime_get_par(x); + b = fp_prime_get_par_sps(&l); + /* First, compute m^(p^12 - 1)(p^4 + 1). */ + fp24_conv_cyc(c, a); + + /* v7 = f^x. */ + fp24_exp_cyc_sps(t[7], c, b, l, bn_sign(x)); + + /* v6 = f^(-2x + 1). */ + fp24_sqr_cyc(t[6], t[7]); + fp24_inv_cyc(t[6], t[6]); + fp24_mul(t[6], t[6], c); + + /* v7 = f^(x^2 - 2x + 1). */ + fp24_exp_cyc_sps(t[7], t[7], b, l, bn_sign(x)); + fp24_mul(t[7], t[7], t[6]); + + fp24_exp_cyc_sps(t[6], t[7], b, l, bn_sign(x)); + + fp24_exp_cyc_sps(t[5], t[6], b, l, bn_sign(x)); + + fp24_exp_cyc_sps(t[4], t[5], b, l, bn_sign(x)); + + fp24_exp_cyc_sps(t[3], t[4], b, l, bn_sign(x)); + fp24_inv_cyc(t[2], t[7]); + fp24_mul(t[3], t[3], t[2]); + + fp24_exp_cyc_sps(t[2], t[3], b, l, bn_sign(x)); + + fp24_exp_cyc_sps(t[1], t[2], b, l, bn_sign(x)); + + /* c = c^3. */ + fp24_sqr_cyc(t[0], c); + fp24_mul(c, c, t[0]); + + fp24_exp_cyc_sps(t[0], t[1], b, l, bn_sign(x)); + + fp24_mul(c, c, t[0]); + for (int i = 1; i < 8; i++) { + fp24_frb(t[i], t[i], i); + fp24_mul(c, c, t[i]); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(x); + for (int i = 0; i < 8; i++) { + fp24_free(t[i]); + } + } +} diff --git a/contrib/relic/src/pp/relic_pp_map.c b/contrib/relic/src/pp/relic_pp_map.c index a718f36fc..389c13bda 100644 --- a/contrib/relic/src/pp/relic_pp_map.c +++ b/contrib/relic/src/pp/relic_pp_map.c @@ -39,8 +39,10 @@ void pp_map_init(void) { ep2_curve_init(); + ep4_curve_init(); } void pp_map_clean(void) { ep2_curve_clean(); + ep4_curve_clean(); } diff --git a/contrib/relic/src/pp/relic_pp_map_k12.c b/contrib/relic/src/pp/relic_pp_map_k12.c index 94d5b0e52..8f4f35ba6 100644 --- a/contrib/relic/src/pp/relic_pp_map_k12.c +++ b/contrib/relic/src/pp/relic_pp_map_k12.c @@ -393,7 +393,7 @@ void pp_map_sim_weilp_k12(fp12_t r, ep_t *p, ep2_t *q, int m) { fp12_null(r0); fp12_null(r1); - bn_null(r); + bn_null(n); RLC_TRY { fp12_new(r0); diff --git a/contrib/relic/src/pp/relic_pp_map_k24.c b/contrib/relic/src/pp/relic_pp_map_k24.c new file mode 100644 index 000000000..70af03e18 --- /dev/null +++ b/contrib/relic/src/pp/relic_pp_map_k24.c @@ -0,0 +1,249 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2019 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Implementation of pairing computation for curves with embedding degree 12. + * + * @ingroup pp + */ + +#include "relic_core.h" +#include "relic_pp.h" +#include "relic_util.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +/** + * Compute the Miller loop for pairings of type G_2 x G_1 over the bits of a + * given parameter represented in sparse form. + * + * @param[out] r - the result. + * @param[out] t - the resulting point. + * @param[in] q - the vector of first arguments in affine coordinates. + * @param[in] p - the vector of second arguments in affine coordinates. + * @param[in] n - the number of pairings to evaluate. + * @param[in] a - the loop parameter. + */ +static void pp_mil_k24(fp24_t r, ep4_t *t, ep4_t *q, ep_t *p, int m, bn_t a) { + fp24_t l; + ep_t *_p = RLC_ALLOCA(ep_t, m); + ep4_t *_q = RLC_ALLOCA(ep4_t, m); + int i, j, len = bn_bits(a) + 1; + int8_t s[RLC_FP_BITS + 1]; + + if (m == 0) { + return; + } + + fp24_null(l); + + RLC_TRY { + fp24_new(l); + if (_p == NULL || _q == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (j = 0; j < m; j++) { + ep_null(_p[j]); + ep4_null(_q[j]); + ep_new(_p[j]); + ep4_new(_q[j]); + ep4_copy(t[j], q[j]); + ep4_neg(_q[j], q[j]); +#if EP_ADD == BASIC + ep_neg(_p[j], p[j]); +#else + fp_add(_p[j]->x, p[j]->x, p[j]->x); + fp_add(_p[j]->x, _p[j]->x, p[j]->x); + fp_neg(_p[j]->y, p[j]->y); +#endif + } + + fp24_zero(l); + bn_rec_naf(s, &len, a, 2); + pp_dbl_k24(r, t[0], t[0], _p[0]); + for (j = 1; j < m; j++) { + pp_dbl_k24(l, t[j], t[j], _p[j]); + fp24_mul_dxs(r, r, l); + } + if (s[len - 2] > 0) { + for (j = 0; j < m; j++) { + pp_add_k24(l, t[j], q[j], p[j]); + fp24_mul_dxs(r, r, l); + } + } + if (s[len - 2] < 0) { + for (j = 0; j < m; j++) { + pp_add_k24(l, t[j], _q[j], p[j]); + fp24_mul_dxs(r, r, l); + } + } + + for (i = len - 3; i >= 0; i--) { + fp24_sqr(r, r); + for (j = 0; j < m; j++) { + pp_dbl_k24(l, t[j], t[j], _p[j]); + fp24_mul(r, r, l); + if (s[i] > 0) { + pp_add_k24(l, t[j], q[j], p[j]); + fp24_mul_dxs(r, r, l); + } + if (s[i] < 0) { + pp_add_k24(l, t[j], _q[j], p[j]); + fp24_mul_dxs(r, r, l); + } + } + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp24_free(l); + for (j = 0; j < m; j++) { + ep_free(_p[j]); + ep4_free(_q[j]); + } + RLC_FREE(_p); + RLC_FREE(_q); + } +} + +/*============================================================================*/ +/* Public definitions */ +/*============================================================================*/ + +#if PP_MAP == OATEP || !defined(STRIP) + +void pp_map_k24(fp24_t r, ep_t p, ep4_t q) { + ep_t _p[1]; + ep4_t t[1], _q[1]; + bn_t a; + + ep_null(_p[0]); + ep4_null(_q[0]); + ep4_null(t[0]); + bn_null(a); + + RLC_TRY { + ep_new(_p[0]); + ep4_new(_q[0]); + ep4_new(t[0]); + bn_new(a); + + fp_prime_get_par(a); + fp24_set_dig(r, 1); + + ep_norm(_p[0], p); + ep4_norm(_q[0], q); + + if (!ep_is_infty(_p[0]) && !ep4_is_infty(_q[0])) { + switch (ep_curve_is_pairf()) { + case EP_B24: + /* r = f_{|a|,Q}(P). */ + pp_mil_k24(r, t, _q, _p, 1, a); + if (bn_sign(a) == RLC_NEG) { + fp24_inv_cyc(r, r); + ep4_neg(t[0], t[0]); + } + pp_exp_k24(r, r); + break; + } + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep_free(_p[0]); + ep4_free(_q[0]); + ep4_free(t[0]); + bn_free(a); + } +} + +void pp_map_sim_k24(fp24_t r, ep_t *p, ep4_t *q, int m) { + ep_t *_p = RLC_ALLOCA(ep_t, m); + ep4_t *t = RLC_ALLOCA(ep4_t, m), *_q = RLC_ALLOCA(ep4_t, m); + bn_t a; + int i, j; + + RLC_TRY { + bn_null(a); + bn_new(a); + if (_p == NULL || _q == NULL || t == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < m; i++) { + ep_null(_p[i]); + ep4_null(_q[i]); + ep4_null(t[i]); + ep_new(_p[i]); + ep4_new(_q[i]); + ep4_new(t[i]); + } + + j = 0; + for (i = 0; i < m; i++) { + if (!ep_is_infty(p[i]) && !ep4_is_infty(q[i])) { + ep_norm(_p[j], p[i]); + ep4_norm(_q[j++], q[i]); + } + } + + fp_prime_get_par(a); + fp24_set_dig(r, 1); + + if (j > 0) { + switch (ep_curve_is_pairf()) { + case EP_B24: + /* r = f_{|a|,Q}(P). */ + pp_mil_k24(r, t, _q, _p, j, a); + if (bn_sign(a) == RLC_NEG) { + fp24_inv_cyc(r, r); + } + pp_exp_k24(r, r); + break; + } + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(a); + for (i = 0; i < m; i++) { + ep_free(_p[i]); + ep4_free(_q[i]); + ep4_free(t[i]); + } + RLC_FREE(_p); + RLC_FREE(_q); + RLC_FREE(t); + } +} + +#endif diff --git a/contrib/relic/src/pp/relic_pp_norm.c b/contrib/relic/src/pp/relic_pp_norm.c index 535c771ae..b2a8f8521 100644 --- a/contrib/relic/src/pp/relic_pp_norm.c +++ b/contrib/relic/src/pp/relic_pp_norm.c @@ -77,8 +77,26 @@ void pp_norm_k12(ep2_t r, ep2_t p) { fp2_inv(r->z, p->z); fp2_mul(r->x, p->x, r->z); fp2_mul(r->y, p->y, r->z); - fp_set_dig(r->z[0], 1); - fp_zero(r->z[1]); + fp2_set_dig(r->z, 1); + r->coord = BASIC; +#endif +} + +void pp_norm_k24(ep4_t r, ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + if (p->coord) { + /* If the point is represented in affine coordinates, we just copy it. */ + ep4_copy(r, p); + } +#if EP_ADD == PROJC || !defined(STRIP) + fp4_inv(r->z, p->z); + fp4_mul(r->x, p->x, r->z); + fp4_mul(r->y, p->y, r->z); + fp4_set_dig(r->z, 1); r->coord = BASIC; #endif } diff --git a/contrib/relic/src/rand/relic_rand_call.c b/contrib/relic/src/rand/relic_rand_call.c index 2422a2579..f59236be6 100644 --- a/contrib/relic/src/rand/relic_rand_call.c +++ b/contrib/relic/src/rand/relic_rand_call.c @@ -77,6 +77,9 @@ void rand_bytes(uint8_t *buf, int size) { ctx_t *ctx = core_get(); ctx->rand_call(buf, size, ctx->rand_args); + if (rand_check(buf, size) == RLC_ERR) { + RLC_THROW(ERR_NO_RAND); + } } void rand_seed(void (*callback)(uint8_t *, int, void *), void *args) { diff --git a/contrib/relic/src/rand/relic_rand_core.c b/contrib/relic/src/rand/relic_rand_core.c index 5ddf6bd27..10f8929f8 100644 --- a/contrib/relic/src/rand/relic_rand_core.c +++ b/contrib/relic/src/rand/relic_rand_core.c @@ -75,6 +75,9 @@ #define RLC_RAND_PATH "/dev/urandom" #endif +/** The maximum number of bytes that can be repeated in the output. */ +#define RAND_REP 6 + /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -180,6 +183,23 @@ void rand_init(void) { #endif } +int rand_check(uint8_t *buf, int size) { + int count = 0; + + for (int i = 1; i < size; i++) { + if (buf[i] == buf[i - 1]) { + count++; + } else { + count = 0; + } + } + + if (count > RAND_REP) { + return RLC_ERR; + } + return RLC_OK; +} + void rand_clean(void) { ctx_t *ctx = core_get(); if (ctx != NULL) { diff --git a/contrib/relic/src/relic_core.c b/contrib/relic/src/relic_core.c index 7a5e6726c..5ec5cf04f 100644 --- a/contrib/relic/src/relic_core.c +++ b/contrib/relic/src/relic_core.c @@ -34,6 +34,7 @@ #include #include "relic_core.h" +#include "relic_bench.h" #include "relic_multi.h" #include "relic_rand.h" #include "relic_types.h" @@ -68,6 +69,8 @@ #define MSG_NO_CURVE "no curve supported at this security level" /** Error message respective to ERR_NO_CONFIG. */ #define MSG_NO_CONFIG "invalid library configuration" +/** Error message respective to ERR_NO_CURVE. */ +#define MSG_NO_RAND "faulty pseudo-random number generator" /*============================================================================*/ /* Public definitions */ @@ -111,6 +114,7 @@ int core_init(void) { core_ctx->reason[ERR_NO_FIELD] = MSG_NO_FIELD; core_ctx->reason[ERR_NO_CURVE] = MSG_NO_CURVE; core_ctx->reason[ERR_NO_CONFIG] = MSG_NO_CONFIG; + core_ctx->reason[ERR_NO_RAND] = MSG_NO_RAND; core_ctx->last = NULL; #endif /* CHECK */ diff --git a/contrib/relic/test/test_bn.c b/contrib/relic/test/test_bn.c index 3b8abde97..ab5eff825 100644 --- a/contrib/relic/test/test_bn.c +++ b/contrib/relic/test/test_bn.c @@ -180,12 +180,16 @@ static int util(void) { TEST_END; TEST_CASE("generating a random integer is consistent") { - bn_rand(b, RLC_POS, RLC_BN_BITS); + do { + bn_rand(b, RLC_POS, RLC_BN_BITS); + } while (bn_is_zero(b)); bn_rand_mod(a, b); TEST_ASSERT(bn_sign(a) == bn_sign(b), end); TEST_ASSERT(bn_is_zero(a) == 0, end); TEST_ASSERT(bn_cmp(a, b) == RLC_LT, end); - bn_rand(b, RLC_NEG, RLC_DIG); + do { + bn_rand(b, RLC_NEG, RLC_DIG); + } while (bn_bits(b) <= 1); bn_rand_mod(a, b); TEST_ASSERT(bn_sign(a) == bn_sign(b), end); TEST_ASSERT(bn_is_zero(a) == 0, end); @@ -1305,7 +1309,7 @@ static int lcm(void) { } static int symbol(void) { - int code = RLC_ERR; + int r, code = RLC_ERR; bn_t a, b, c, p, q; bn_null(a); @@ -1327,35 +1331,33 @@ static int symbol(void) { } while (bn_is_even(p) || bn_is_even(q)); TEST_CASE("legendre symbol is correct") { - bn_smb_leg(c, p, p); - TEST_ASSERT(bn_is_zero(c) == 1, end); + TEST_ASSERT(bn_smb_leg(p, p) == 0, end); bn_rand(a, RLC_POS, RLC_BN_BITS); bn_sqr(a, a); bn_mod(a, a, p); - bn_smb_leg(c, a, p); - TEST_ASSERT(bn_cmp_dig(c, 1) == RLC_EQ, end); + TEST_ASSERT(bn_smb_leg(a, p) == 1, end); bn_rand(a, RLC_POS, RLC_BN_BITS); - bn_smb_leg(c, a, p); - bn_set_dig(a, 1); - TEST_ASSERT(bn_cmp_abs(c, a) == RLC_EQ, end); + r = bn_smb_leg(a, p); + TEST_ASSERT(r == 1 || r == -1, end); } TEST_END; TEST_CASE("legendre symbol is a homomorphism") { bn_rand(a, RLC_POS, RLC_BN_BITS / 2); bn_rand(b, RLC_POS, RLC_BN_BITS / 2); bn_mul(c, a, b); - bn_smb_leg(a, a, p); - bn_smb_leg(b, b, p); - bn_smb_leg(c, c, p); - bn_mul(a, a, b); - TEST_ASSERT(bn_cmp(a, c) == RLC_EQ, end); + r = bn_smb_leg(a, p) * bn_smb_leg(b, p); + TEST_ASSERT(r == bn_smb_leg(c, p), end); } TEST_END; TEST_ONCE("legendre symbol satisfies quadratic reciprocity") { /* Check the first supplement: (-1|p) = (-1)^(p-1)/2. */ bn_set_dig(a, 1); bn_neg(a, a); - bn_smb_leg(b, a, p); + r = bn_smb_leg(a, p); + bn_set_dig(b, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(b, b); + } bn_sub_dig(c, p, 1); bn_rsh(c, c, 1); if (bn_is_even(c)) { @@ -1364,7 +1366,11 @@ static int symbol(void) { TEST_ASSERT(bn_cmp(a, b) == RLC_EQ, end); /* Check second supplement: (2|p) = (-1)^(p^2-1)/8. */ bn_set_dig(a, 2); - bn_smb_leg(b, a, p); + r = bn_smb_leg(a, p); + bn_set_dig(b, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(b, b); + } bn_sqr(c, p); bn_sub_dig(c, c, 1); bn_rsh(c, c, 3); @@ -1374,8 +1380,16 @@ static int symbol(void) { } TEST_ASSERT(bn_cmp(a, b) == RLC_EQ, end); /* Check quadratic reciprocity law. */ - bn_smb_leg(a, q, p); - bn_smb_leg(b, p, q); + r = bn_smb_leg(q, p); + bn_set_dig(a, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(a, a); + } + r = bn_smb_leg(p, q); + bn_set_dig(b, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(b, b); + } bn_sub_dig(c, p, 1); bn_rsh(c, c, 1); if (!bn_is_even(c)) { @@ -1390,9 +1404,7 @@ static int symbol(void) { TEST_CASE("jacobi symbol is correct") { bn_rand(a, RLC_POS, RLC_BN_BITS); - bn_smb_leg(c, a, p); - bn_smb_jac(b, a, p); - TEST_ASSERT(bn_cmp_abs(c, b) == RLC_EQ, end); + TEST_ASSERT(bn_smb_leg(a, p) == bn_smb_jac(a, p), end); } TEST_END; TEST_CASE("jacobi symbol is a homomorphism") { @@ -1403,11 +1415,8 @@ static int symbol(void) { bn_add_dig(p, p, 1); } bn_mul(c, a, b); - bn_smb_jac(a, a, p); - bn_smb_jac(b, b, p); - bn_smb_jac(c, c, p); - bn_mul(a, a, b); - TEST_ASSERT(bn_cmp(a, c) == RLC_EQ, end); + r = bn_smb_jac(a, p) * bn_smb_jac(b, p); + TEST_ASSERT(r == bn_smb_jac(c, p), end); } TEST_END; TEST_CASE("jacobi symbol is consistent with gcd") { @@ -1416,13 +1425,16 @@ static int symbol(void) { if (bn_is_even(p)) { bn_add_dig(p, p, 1); } - bn_smb_jac(c, a, p); + r = bn_smb_jac(a, p); + bn_set_dig(c, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(c, c); + } bn_gcd(b, a, p); if (bn_cmp_dig(b, 1) != RLC_EQ) { - TEST_ASSERT(bn_is_zero(c), end); + TEST_ASSERT(r == 0, end); } else { - bn_set_dig(a, 1); - TEST_ASSERT(bn_cmp_abs(c, a) == RLC_EQ, end); + TEST_ASSERT(r == 1 || r == -1, end); } } TEST_END; @@ -1438,7 +1450,11 @@ static int symbol(void) { /* Check the first supplement: (-1|n) = (-1)^(n-1)/2. */ bn_set_dig(a, 1); bn_neg(a, a); - bn_smb_jac(b, a, p); + r = bn_smb_jac(a, p); + bn_set_dig(b, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(b, b); + } bn_sub_dig(c, p, 1); bn_rsh(c, c, 1); if (bn_is_even(c)) { @@ -1447,7 +1463,11 @@ static int symbol(void) { TEST_ASSERT(bn_cmp(a, b) == RLC_EQ, end); /* Check second supplement: (2|p) = (-1)^(p^2-1)/8. */ bn_set_dig(a, 2); - bn_smb_jac(b, a, p); + r = bn_smb_jac(a, p); + bn_set_dig(b, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(b, b); + } bn_sqr(c, p); bn_sub_dig(c, c, 1); bn_rsh(c, c, 3); @@ -1457,8 +1477,16 @@ static int symbol(void) { } TEST_ASSERT(bn_cmp(a, b) == RLC_EQ, end); /* Check quadratic reciprocity law. */ - bn_smb_jac(a, p, q); - bn_smb_jac(b, q, p); + r = bn_smb_jac(p, q); + bn_set_dig(a, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(a, a); + } + r = bn_smb_jac(q, p); + bn_set_dig(b, (r < 0 ? -r : r)); + if (r < 0) { + bn_neg(b, b); + } bn_sub_dig(c, p, 1); bn_rsh(c, c, 1); if (!bn_is_even(c)) { @@ -1738,16 +1766,20 @@ static int small_primes(void) { static int inversion(void) { int code = RLC_ERR; - bn_t a, b, c; + bn_t a, b, c, d[2]; bn_null(a); bn_null(b); bn_null(c); + bn_null(d[0]); + bn_null(d[1]); RLC_TRY { bn_new(a); bn_new(b); bn_new(c); + bn_new(d[0]); + bn_new(d[1]); bn_gen_prime(a, RLC_BN_BITS); @@ -1758,6 +1790,17 @@ static int inversion(void) { bn_mul(c, b, c); bn_mod(c, c, a); TEST_ASSERT(bn_cmp_dig(c, 1) == RLC_EQ, end); + bn_rand_mod(b, a); + bn_rand_mod(c, a); + bn_copy(d[0], b); + bn_copy(d[1], c); + bn_mod_inv_sim(d, d, a, 2); + bn_mul(b, b, d[0]); + bn_mod(b, b, a); + bn_mul(c, c, d[1]); + bn_mod(c, c, a); + TEST_ASSERT(bn_cmp_dig(b, 1) == RLC_EQ, end); + TEST_ASSERT(bn_cmp_dig(c, 1) == RLC_EQ, end); } TEST_END; } RLC_CATCH_ANY { @@ -1768,6 +1811,8 @@ static int inversion(void) { bn_free(a); bn_free(b); bn_free(c); + bn_free(d[0]); + bn_free(d[1]); return code; } @@ -1811,7 +1856,7 @@ static int recoding(void) { bn_t a, b, c, v1[3], v2[3]; int w, k, l; uint8_t d[RLC_BN_BITS + 1]; - signed char e[2 * (RLC_BN_BITS + 1)]; + int8_t e[2 * (RLC_BN_BITS + 1)]; bn_null(a); bn_null(b); diff --git a/contrib/relic/test/test_core.c b/contrib/relic/test/test_core.c index 4cdabdb22..a7642f08f 100644 --- a/contrib/relic/test/test_core.c +++ b/contrib/relic/test/test_core.c @@ -34,6 +34,7 @@ #include "relic.h" #include "relic_test.h" +#if defined(MULTI) #if MULTI == PTHREAD void *master(void *ptr) { @@ -61,6 +62,7 @@ void *tester(void *ptr) { return NULL; } +#endif #endif int main(void) { @@ -100,6 +102,7 @@ int main(void) { code = RLC_OK; +#if defined(MULTI) #if MULTI == OPENMP TEST_ONCE("library context is thread-safe") { omp_set_num_threads(CORES); @@ -158,6 +161,7 @@ int main(void) { } TEST_ASSERT(code == RLC_OK, end); } TEST_END; +#endif #endif util_banner("All tests have passed.\n", 0); diff --git a/contrib/relic/test/test_cp.c b/contrib/relic/test/test_cp.c index cdba96433..0a4a15959 100644 --- a/contrib/relic/test/test_cp.c +++ b/contrib/relic/test/test_cp.c @@ -462,7 +462,7 @@ static int ecies(void) { ec_new(q_b); l = ec_param_level(); - if (l == 128 || l == 192 || l == 256) { + if (l == 80 || l == 128 || l == 192 || l == 256) { TEST_CASE("ecies encryption/decryption is correct") { TEST_ASSERT(cp_ecies_gen(da, qa) == RLC_OK, end); in_len = RLC_BC_LEN - 1; @@ -673,10 +673,520 @@ static int vbnn(void) { return code; } +static int pok(void) { + int code = RLC_ERR; + bn_t c[2], n, r[2], x; + ec_t y[2]; + + bn_null(n); + bn_null(x); + + RLC_TRY { + bn_new(n); + bn_new(x); + for (int i = 0; i < 2; i++) { + bn_null(c[i]); + bn_null(r[i]); + ec_null(y[i]); + bn_new(c[i]); + bn_new(r[i]); + ec_new(y[i]); + } + ec_curve_get_ord(n); + + TEST_CASE("proof of knowledge of discrete logarithm is correct") { + bn_rand_mod(x, n); + ec_mul_gen(y[0], x); + TEST_ASSERT(cp_pokdl_prv(c[0], r[0], y[0], x) == RLC_OK, end); + TEST_ASSERT(cp_pokdl_ver(c[0], r[0], y[0]) == 1, end); + ec_dbl(y[0], y[0]); + ec_norm(y[0], y[0]); + TEST_ASSERT(cp_pokdl_ver(c[0], r[0], y[0]) == 0, end); + } TEST_END; + + TEST_CASE("proof of knowledge of disjunction is correct") { + bn_rand_mod(x, n); + do { + ec_rand(y[0]); + ec_mul_gen(y[1], x); + } while (ec_cmp(y[0], y[1]) == RLC_EQ); + TEST_ASSERT(cp_pokor_prv(c, r, y, x) == RLC_OK, end); + TEST_ASSERT(cp_pokor_ver(c, r, y) == 1, end); + ec_dbl(y[1], y[1]); + ec_norm(y[1], y[1]); + TEST_ASSERT(cp_pokor_ver(c, r, y) == 0, end); + } TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + +end: + bn_free(n); + bn_free(x); + for (int i = 0; i < 2; i++) { + bn_free(c[i]); + bn_free(r[i]); + ec_free(y[i]); + } + return code; +} + +static int sok(void) { + int code = RLC_ERR; + bn_t c[2], n, r[2], x; + ec_t g[2], y[2]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + bn_null(n); + bn_null(x); + + RLC_TRY { + bn_new(n); + bn_new(x); + for (int i = 0; i < 2; i++) { + bn_null(c[i]); + bn_null(r[i]); + ec_null(g[i]); + ec_null(y[i]); + bn_new(c[i]); + bn_new(r[i]); + ec_new(g[i]); + ec_new(y[i]); + } + ec_curve_get_ord(n); + + TEST_CASE("signature of knowledge of discrete logarithm is correct") { + bn_rand_mod(x, n); + ec_mul_gen(y[0], x); + TEST_ASSERT(cp_sokdl_sig(c[0], r[0], m, 5, y[0], x) == RLC_OK, end); + TEST_ASSERT(cp_sokdl_ver(c[0], r[0], m, 5, y[0]) == 1, end); + ec_dbl(y[0], y[0]); + ec_norm(y[0], y[0]); + TEST_ASSERT(cp_sokdl_ver(c[0], r[0], m, 5, y[0]) == 0, end); + } TEST_END; + + TEST_CASE("signature of knowledge of disjunction is correct") { + bn_rand_mod(x, n); + do { + ec_rand(y[0]); + ec_mul_gen(y[1], x); + } while (ec_cmp(y[0], y[1]) == RLC_EQ); + TEST_ASSERT(cp_sokor_sig(c, r, m, 5, y, NULL, x, 0) == RLC_OK, end); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, NULL) == 1, end); + ec_dbl(y[1], y[1]); + ec_norm(y[1], y[1]); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, NULL) == 0, end); + do { + ec_mul_gen(y[0], x); + ec_rand(y[1]); + } while (ec_cmp(y[0], y[1]) == RLC_EQ); + TEST_ASSERT(cp_sokor_sig(c, r, m, 5, y, NULL, x, 1) == RLC_OK, end); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, NULL) == 1, end); + ec_dbl(y[0], y[0]); + ec_norm(y[0], y[0]); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, NULL) == 0, end); + do { + ec_curve_get_gen(g[0]); + ec_rand(g[1]); + ec_rand(y[0]); + ec_mul(y[1], g[1], x); + } while (ec_cmp(y[0], y[1]) == RLC_EQ); + TEST_ASSERT(cp_sokor_sig(c, r, m, 5, y, g, x, 0) == RLC_OK, end); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, g) == 1, end); + ec_dbl(y[1], y[1]); + ec_norm(y[1], y[1]); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, g) == 0, end); + do { + ec_rand(g[0]); + ec_mul(y[0], g[0], x); + ec_curve_get_gen(g[1]); + ec_rand(y[1]); + } while (ec_cmp(y[0], y[1]) == RLC_EQ); + TEST_ASSERT(cp_sokor_sig(c, r, m, 5, y, g, x, 1) == RLC_OK, end); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, g) == 1, end); + ec_dbl(y[0], y[0]); + ec_norm(y[0], y[0]); + TEST_ASSERT(cp_sokor_ver(c, r, m, 5, y, g) == 0, end); + } TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + +end: + bn_free(n); + bn_free(x); + for (int i = 0; i < 2; i++) { + bn_free(c[i]); + bn_free(r[i]); + ec_free(g[i]); + ec_free(y[i]); + } + return code; +} + +static int ers(void) { + int size, code = RLC_ERR; + ec_t pp, pk[4]; + bn_t sk[4], td; + ers_t ring[4]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + bn_null(td); + ec_null(pp); + + RLC_TRY { + bn_new(td); + ec_new(pp); + for (int i = 0; i < 4; i++) { + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + ers_null(ring[i]); + ers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + TEST_CASE("extendable ring signature scheme is correct") { + TEST_ASSERT(cp_ers_sig(td, ring[0], m, 5, sk[0], pk[0], pp) == RLC_OK, end); + TEST_ASSERT(cp_ers_ver(td, ring, 1, m, 5, pp) == 1, end); + TEST_ASSERT(cp_ers_ver(td, ring, 1, m, 0, pp) == 0, end); + size = 1; + for (int j = 1; j < 4; j++) { + TEST_ASSERT(cp_ers_ext(td, ring, &size, m, 5, pk[j], pp) == RLC_OK, end); + TEST_ASSERT(cp_ers_ver(td, ring, size, m, 5, pp) == 1, end); + TEST_ASSERT(cp_ers_ver(td, ring, size, m, 0, pp) == 0, end); + } + } TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + +end: + bn_free(td); + ec_free(pp); + for (int i = 0; i < 4; i++) { + bn_free(sk[i]); + ec_free(pk[i]); + ers_free(ring[i]) + } + return code; +} + +static int smlers(void) { + int size, code = RLC_ERR; + ec_t pp, pk[4]; + bn_t sk[4], td; + smlers_t ring[4]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + bn_null(td); + ec_null(pp); + + RLC_TRY { + bn_new(td); + ec_new(pp); + for (int i = 0; i < 4; i++) { + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + smlers_null(ring[i]); + smlers_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + TEST_CASE("same-message linkable ext. ring signature scheme is correct") { + TEST_ASSERT(cp_smlers_sig(td, ring[0], m, 5, sk[0], pk[0], pp) == RLC_OK, end); + TEST_ASSERT(cp_smlers_ver(td, ring, 1, m, 5, pp) == 1, end); + TEST_ASSERT(cp_smlers_ver(td, ring, 1, m, 0, pp) == 0, end); + size = 1; + for (int j = 1; j < 4; j++) { + TEST_ASSERT(cp_smlers_ext(td, ring, &size, m, 5, pk[j], pp) == RLC_OK, end); + TEST_ASSERT(cp_smlers_ver(td, ring, size, m, 5, pp) == 1, end); + TEST_ASSERT(cp_smlers_ver(td, ring, size, m, 0, pp) == 0, end); + TEST_ASSERT(ec_cmp(ring[0]->tau, ring[j]->tau) == RLC_EQ, end); + } + } TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + +end: + bn_free(td); + ec_free(pp); + for (int i = 0; i < 4; i++) { + bn_free(sk[i]); + ec_free(pk[i]); + smlers_free(ring[i]) + } + return code; +} + +static int etrs(void) { + int size, code = RLC_ERR; + ec_t pp, pk[4]; + bn_t sk[4], td[4], y[4]; + etrs_t ring[4]; + uint8_t m[5] = { 0, 1, 2, 3, 4 }; + + + ec_null(pp); + + RLC_TRY { + ec_new(pp); + for (int i = 0; i < 4; i++) { + bn_null(td[i]); + bn_new(td[i]); + bn_null(y[i]); + bn_new(y[i]); + bn_null(sk[i]); + bn_new(sk[i]); + ec_null(pk[i]); + ec_new(pk[i]); + etrs_null(ring[i]); + etrs_new(ring[i]); + cp_ers_gen_key(sk[i], pk[i]); + } + + cp_ers_gen(pp); + + TEST_CASE("extendable threshold ring signature scheme is correct") { + TEST_ASSERT(cp_etrs_sig(td, y, 4, ring[0], m, 5, sk[0], pk[0], pp) == RLC_OK, end); + TEST_ASSERT(cp_etrs_ver(0, td, y, 4, ring, 1, m, 5, pp) == 0, end); + TEST_ASSERT(cp_etrs_ver(1, td, y, 4, ring, 1, m, 5, pp) == 1, end); + TEST_ASSERT(cp_etrs_ver(1, td, y, 4, ring, 1, m, 0, pp) == 0, end); + size = 1; + for (int j = 1; j < 4; j++) { + TEST_ASSERT(cp_etrs_ext(td, y, 4, ring, &size, m, 5, pk[j], pp) == RLC_OK, end); + TEST_ASSERT(cp_etrs_ver(0, td+j, y+j, 4-j, ring, size, m, 5, pp) == 0, end); + TEST_ASSERT(cp_etrs_ver(1, td+j, y+j, 4-j, ring, size, m, 5, pp) == 1, end); + TEST_ASSERT(cp_etrs_ver(1, td+j, y+j, 4-j, ring, size, m, 0, pp) == 0, end); + } + + TEST_ASSERT(cp_etrs_sig(td, y, 4, ring[0], m, 5, sk[0], pk[0], pp) == RLC_OK, end); + size = 1; + TEST_ASSERT(cp_etrs_uni(1, td, y, 4, ring, &size, m, 5, sk[1], pk[1], pp) == RLC_OK, end); + TEST_ASSERT(cp_etrs_ver(1, td, y, 4, ring, size, m, 5, pp) == 0, end); + TEST_ASSERT(cp_etrs_ver(2, td, y, 4, ring, size, m, 5, pp) == 1, end); + TEST_ASSERT(cp_etrs_ver(2, td, y, 4, ring, size, m, 0, pp) == 0, end); + for (int j = 2; j < 4; j++) { + TEST_ASSERT(cp_etrs_ext(td, y, 4, ring, &size, m, 5, pk[j], pp) == RLC_OK, end); + TEST_ASSERT(cp_etrs_ver(1, td+j-1, y+j-1, 4-j+1, ring, size, m, 5, pp) == 0, end); + TEST_ASSERT(cp_etrs_ver(2, td+j-1, y+j-1, 4-j+1, ring, size, m, 5, pp) == 1, end); + TEST_ASSERT(cp_etrs_ver(2, td+j-1, y+j-1, 4-j+1, ring, size, m, 0, pp) == 0, end); + } + } TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + +end: + ec_free(pp); + for (int i = 0; i < 4; i++) { + bn_free(td[i]); + bn_free(y[i]); + bn_free(sk[i]); + ec_free(pk[i]); + etrs_free(ring[i]) + } + return code; +} + #endif /* WITH_EC */ #if defined(WITH_PC) +static int pdpub(void) { + int code = RLC_ERR; + bn_t r1, r2; + g1_t p, u1, v1; + g2_t q, u2, v2, w2; + gt_t e, r, g[3]; + + bn_null(r1); + bn_null(r2); + g1_null(p); + g1_null(u1); + g1_null(v1); + g2_null(q); + g2_null(u2); + g2_null(v2); + g2_null(w2); + gt_null(e); + gt_null(r); + gt_null(g[0]); + gt_null(g[1]); + gt_null(g[2]); + + RLC_TRY { + bn_new(r1); + bn_new(r2); + g1_new(p); + g1_new(u1); + g1_new(v1); + g2_new(q); + g2_new(u2); + g2_new(v2); + g2_new(w2); + gt_new(e); + gt_new(r); + gt_new(g[0]); + gt_new(g[1]); + gt_new(g[2]); + + TEST_CASE("delegated pairing computation with public inputs is correct") { + TEST_ASSERT(cp_pdpub_gen(r1, r2, u1, u2, v2, e) == RLC_OK, end); + g1_rand(p); + g2_rand(q); + TEST_ASSERT(cp_pdpub_ask(v1, w2, p, q, r1, r2, u1, u2, v2) == RLC_OK, end); + TEST_ASSERT(cp_pdpub_ans(g, p, q, v1, v2, w2) == RLC_OK, end); + TEST_ASSERT(cp_pdpub_ver(r, g, r1, e) == 1, end); + pc_map(e, p, q); + TEST_ASSERT(gt_cmp(r, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("faster delegated pairing with public inputs is correct") { + TEST_ASSERT(cp_lvpub_gen(r2, u1, u2, v2, e) == RLC_OK, end); + g1_rand(p); + g2_rand(q); + TEST_ASSERT(cp_lvpub_ask(r1, v1, w2, p, q, r2, u1, u2, v2) == RLC_OK, end); + TEST_ASSERT(cp_lvpub_ans(g, p, q, v1, v2, w2) == RLC_OK, end); + TEST_ASSERT(cp_lvpub_ver(r, g, r1, e) == 1, end); + pc_map(e, p, q); + TEST_ASSERT(gt_cmp(r, e) == RLC_EQ, end); + } TEST_END; + } RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + + end: + bn_free(r1); + bn_free(r2); + g1_free(p); + g1_free(u1); + g1_free(v1); + g2_free(q); + g2_free(u2); + g2_free(v2); + g2_free(w2); + gt_free(e); + gt_free(r); + gt_free(g[0]); + gt_free(g[1]); + gt_free(g[2]); + return code; +} + +static int pdprv(void) { + int code = RLC_ERR; + bn_t r1, r2[3]; + g1_t p, u1[2], v1[3]; + g2_t q, u2[2], v2[4], w2[4]; + gt_t e[2], r, g[4]; + + bn_null(r1); + g1_null(p); + g2_null(q); + gt_null(r); + for (int i = 0; i < 2; i++) { + g1_null(u1[i]); + g2_null(u2[i]); + gt_null(e[i]); + } + for (int i = 0; i < 3; i++) { + g1_null(v1[i]); + bn_null(r2[i]); + } + for (int i = 0; i < 4; i++) { + g2_null(v2[i]); + g2_null(w2[i]); + gt_null(g[i]); + } + + RLC_TRY { + bn_new(r1); + g1_new(p); + g2_new(q); + gt_new(r); + for (int i = 0; i < 2; i++) { + g1_new(u1[i]); + g2_new(u2[i]); + gt_new(e[i]); + } + for (int i = 0; i < 3; i++) { + g1_new(v1[i]); + bn_new(r2[i]); + } + for (int i = 0; i < 4; i++) { + g2_new(v2[i]); + g2_new(w2[i]); + gt_new(g[i]); + } + + TEST_CASE("delegated pairing computation with private inputs is correct") { + TEST_ASSERT(cp_pdprv_gen(r1, r2, u1, u2, v2, e) == RLC_OK, end); + g1_rand(p); + g2_rand(q); + TEST_ASSERT(cp_pdprv_ask(v1, w2, p, q, r1, r2, u1, u2, v2) == RLC_OK, end); + TEST_ASSERT(cp_pdprv_ans(g, v1, w2) == RLC_OK, end); + TEST_ASSERT(cp_pdprv_ver(r, g, r1, e) == 1, end); + pc_map(e[0], p, q); + TEST_ASSERT(gt_cmp(r, e[0]) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("faster delegated pairing with private inputs is correct") { + TEST_ASSERT(cp_pdprv_gen(r1, r2, u1, u2, v2, e) == RLC_OK, end); + g1_rand(p); + g2_rand(q); + TEST_ASSERT(cp_lvprv_ask(v1, w2, p, q, r1, r2, u1, u2, v2) == RLC_OK, end); + TEST_ASSERT(cp_lvprv_ans(g, v1, w2) == RLC_OK, end); + TEST_ASSERT(cp_lvprv_ver(r, g, r1, e) == 1, end); + pc_map(e[0], p, q); + TEST_ASSERT(gt_cmp(r, e[0]) == RLC_EQ, end); + } TEST_END; + } RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + + end: + bn_free(r1); + g1_free(p); + g2_free(q); + gt_free(r); + for (int i = 0; i < 2; i++) { + g1_free(u1[i]); + g2_free(u2[i]); + gt_free(e[i]); + } + for (int i = 0; i < 3; i++) { + g1_free(v1[i]); + bn_free(r2[i]); + } + for (int i = 0; i < 4; i++) { + g2_free(v2[i]); + g2_free(w2[i]); + gt_free(g[i]); + } + return code; +} + static int sokaka(void) { int code = RLC_ERR, l = RLC_MD_LEN; sokaka_t k; @@ -1506,36 +2016,115 @@ static int lhs(void) { code = RLC_OK; end: - bn_free(n); - bn_free(m); - g1_free(h); - g1_free(_r); - g2_free(_s); - gt_free(vk); - - for (int i = 0; i < S; i++) { - RLC_FREE(f[i]); - for (int j = 0; j < RLC_TERMS; j++) { + bn_free(n); + bn_free(m); + g1_free(h); + g1_free(_r); + g2_free(_s); + gt_free(vk); + + for (int i = 0; i < S; i++) { + RLC_FREE(f[i]); + for (int j = 0; j < RLC_TERMS; j++) { gt_free(hs[i][j]); - } - RLC_FREE(hs[i]); - for (int j = 0; j < L; j++) { - bn_free(x[i][j]); - bn_free(msg[i][j]); - g1_free(a[i][j]); - g1_free(c[i][j]); - g1_free(r[i][j]); - g2_free(s[i][j]); - } - bn_free(sk[i]); - bn_free(d[i]); - g1_free(sig[i]); - g1_free(as[i]); - g1_free(cs[i]); - g2_free(y[i]); - g2_free(z[i]); - g2_free(pk[i]); - } + } + RLC_FREE(hs[i]); + for (int j = 0; j < L; j++) { + bn_free(x[i][j]); + bn_free(msg[i][j]); + g1_free(a[i][j]); + g1_free(c[i][j]); + g1_free(r[i][j]); + g2_free(s[i][j]); + } + bn_free(sk[i]); + bn_free(d[i]); + g1_free(sig[i]); + g1_free(as[i]); + g1_free(cs[i]); + g2_free(y[i]); + g2_free(z[i]); + g2_free(pk[i]); + } + return code; +} + +#define M 5 /* Number of server messages (larger). */ +#define N 2 /* Number of client messages. */ + +static int psi(void) { + int len, code = RLC_ERR; + bn_t q, r, x[M], y[N], z[M]; + g1_t d, s[M + 1]; + g2_t u[M], ss; + gt_t t[M]; + + bn_null(q); + bn_null(r); + g1_null(d); + g2_null(ss); + + RLC_TRY { + bn_new(q); + bn_new(r); + g1_new(d); + g2_new(ss); + for (int i = 0; i < M; i++) { + bn_null(x[i]); + bn_null(z[i]); + g1_null(s[i]); + bn_new(x[i]); + bn_new(z[i]); + g1_new(s[i]); + } + for (int i = 0; i < N; i++) { + bn_null(y[i]); + g2_null(u[i]); + gt_null(t[i]); + bn_new(y[i]); + g2_new(u[i]); + gt_new(t[i]); + } + + TEST_CASE("laconic private set intersection is correct") { + pc_get_ord(q); + for (int j = 0; j < M; j++) { + bn_rand_mod(x[j], q); + } + for (int j = 0; j < N; j++) { + bn_rand_mod(y[j], q); + } + TEST_ASSERT(cp_lapsi_gen(q, ss, s, M) == RLC_OK, end); + TEST_ASSERT(cp_lapsi_ask(d, r, x, s, M) == RLC_OK, end); + for (int k = 0; k <= N; k++) { + for (int j = 0; j < k; j++) { + bn_copy(y[j], x[j]); + } + TEST_ASSERT(cp_lapsi_ans(t, u, d, ss, y, N) == RLC_OK, end); + TEST_ASSERT(cp_lapsi_int(z, &len, q, d, x, M, t, u, N) == RLC_OK, end); + TEST_ASSERT(len == k, end); + } + } TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(q); + bn_free(r); + g1_free(d); + g2_free(ss); + for (int i = 0; i < M; i++) { + bn_free(x[i]); + bn_free(z[i]); + g1_free(s[i]); + } + for (int i = 0; i < N; i++) { + bn_free(y[i]); + g2_free(u[i]); + gt_free(t[i]); + } return code; } @@ -1609,14 +2198,45 @@ int main(void) { return 1; } - } else { - RLC_THROW(ERR_NO_CURVE); + if (pok() != RLC_OK) { + core_clean(); + return 1; + } + + if (sok() != RLC_OK) { + core_clean(); + return 1; + } + + if (ers() != RLC_OK) { + core_clean(); + return 1; + } + + if (smlers() != RLC_OK) { + core_clean(); + return 1; + } + + if (etrs() != RLC_OK) { + core_clean(); + return 1; + } } #endif #if defined(WITH_PC) util_banner("Protocols based on pairings:\n", 0); if (pc_param_set_any() == RLC_OK) { + if (pdpub() != RLC_OK) { + core_clean(); + return 1; + } + + if (pdprv() != RLC_OK) { + core_clean(); + return 1; + } if (sokaka() != RLC_OK) { core_clean(); @@ -1669,8 +2289,11 @@ int main(void) { core_clean(); return 1; } - } else { - RLC_THROW(ERR_NO_CURVE); + + if (psi() != RLC_OK) { + core_clean(); + return 1; + } } #endif diff --git a/contrib/relic/test/test_eb.c b/contrib/relic/test/test_eb.c index ab58a165e..5b0198302 100644 --- a/contrib/relic/test/test_eb.c +++ b/contrib/relic/test/test_eb.c @@ -633,7 +633,7 @@ static int multiplication(void) { eb_mul_basic(r, p, k); TEST_ASSERT(eb_cmp(p, r) == RLC_EQ, end); eb_rand(p); - eb_mul(r, p, n); + eb_mul_basic(r, p, n); TEST_ASSERT(eb_is_infty(r), end); bn_rand_mod(k, n); eb_mul(q, p, k); @@ -655,7 +655,7 @@ static int multiplication(void) { eb_mul_lodah(r, p, k); TEST_ASSERT(eb_cmp(p, r) == RLC_EQ, end); eb_rand(p); - eb_mul(r, p, n); + eb_mul_lodah(r, p, n); TEST_ASSERT(eb_is_infty(r), end); bn_rand_mod(k, n); eb_mul(q, p, k); @@ -678,7 +678,7 @@ static int multiplication(void) { eb_mul_lwnaf(r, p, k); TEST_ASSERT(eb_cmp(p, r) == RLC_EQ, end); eb_rand(p); - eb_mul(r, p, n); + eb_mul_lwnaf(r, p, n); TEST_ASSERT(eb_is_infty(r), end); bn_rand_mod(k, n); eb_mul(q, p, k); @@ -701,7 +701,7 @@ static int multiplication(void) { eb_mul_rwnaf(r, p, k); TEST_ASSERT(eb_cmp(p, r) == RLC_EQ, end); eb_rand(p); - eb_mul(r, p, n); + eb_mul_rwnaf(r, p, n); TEST_ASSERT(eb_is_infty(r), end); bn_rand_mod(k, n); eb_mul(q, p, k); @@ -724,7 +724,7 @@ static int multiplication(void) { eb_mul_halve(r, p, k); TEST_ASSERT(eb_cmp(p, r) == RLC_EQ, end); eb_rand(p); - eb_mul(r, p, n); + eb_mul_halve(r, p, n); TEST_ASSERT(eb_is_infty(r), end); bn_rand_mod(k, n); eb_mul(q, p, k); @@ -738,7 +738,7 @@ static int multiplication(void) { TEST_END; #endif - TEST_CASE("multiplication by digit is correct") { + TEST_CASE("point multiplication by digit is correct") { eb_mul_dig(r, p, 0); TEST_ASSERT(eb_is_infty(r), end); eb_mul_dig(r, p, 1); diff --git a/contrib/relic/test/test_ec.c b/contrib/relic/test/test_ec.c index ba068bf42..63e89d6c7 100644 --- a/contrib/relic/test/test_ec.c +++ b/contrib/relic/test/test_ec.c @@ -389,6 +389,18 @@ static int multiplication(void) { ec_neg(r, r); TEST_ASSERT(ec_cmp(q, r) == RLC_EQ, end); } TEST_END; + + TEST_CASE("point multiplication by digit is correct") { + ec_mul_dig(r, p, 0); + TEST_ASSERT(ec_is_infty(r), end); + ec_mul_dig(r, p, 1); + TEST_ASSERT(ec_cmp(p, r) == RLC_EQ, end); + bn_rand(k, RLC_POS, RLC_DIG); + ec_mul(q, p, k); + ec_mul_dig(r, p, k->dp[0]); + TEST_ASSERT(ec_cmp(q, r) == RLC_EQ, end); + } + TEST_END; } RLC_CATCH_ANY { util_print("FATAL ERROR!\n"); diff --git a/contrib/relic/test/test_ed.c b/contrib/relic/test/test_ed.c index 2698075e1..e1e371f26 100644 --- a/contrib/relic/test/test_ed.c +++ b/contrib/relic/test/test_ed.c @@ -673,7 +673,7 @@ static int multiplication(void) { TEST_END; #endif - TEST_CASE("multiplication by digit is correct") { + TEST_CASE("point multiplication by digit is correct") { ed_mul_dig(r, p, 0); TEST_ASSERT(ed_is_infty(r), end); ed_mul_dig(r, p, 1); diff --git a/contrib/relic/test/test_ep.c b/contrib/relic/test/test_ep.c index cde15d20b..2e6e4ed9d 100644 --- a/contrib/relic/test/test_ep.c +++ b/contrib/relic/test/test_ep.c @@ -496,28 +496,28 @@ static int endomorphism(void) { bn_new(v2[k]); } - /* Recover lambda parameter. */ - ep_curve_get_v1(v1); - ep_curve_get_v2(v2); - ep_curve_get_ord(v2[0]); - if (bn_cmp_dig(v1[2], 1) == RLC_EQ) { - bn_gcd_ext(v1[0], v2[1], NULL, v1[1], v2[0]); - } else { - bn_gcd_ext(v1[0], v2[1], NULL, v1[2], v2[0]); - } - if (bn_sign(v2[1]) == RLC_NEG) { - /* Negate modulo r. */ - bn_add(v2[1], v2[0], v2[1]); - } - bn_mul(v1[0], v2[1], v1[1]); - bn_mod(l, v1[0], v2[0]); - bn_sub(v1[1], v2[0], l); - if (bn_cmp(v1[1], l) == RLC_LT) { - bn_copy(l, v1[1]); - } - #if defined(EP_ENDOM) if (ep_curve_is_endom()) { + /* Recover lambda parameter. */ + ep_curve_get_v1(v1); + ep_curve_get_v2(v2); + ep_curve_get_ord(v2[0]); + if (bn_cmp_dig(v1[2], 1) == RLC_EQ) { + bn_gcd_ext(v1[0], v2[1], NULL, v1[1], v2[0]); + } else { + bn_gcd_ext(v1[0], v2[1], NULL, v1[2], v2[0]); + } + if (bn_sign(v2[1]) == RLC_NEG) { + /* Negate modulo r. */ + bn_add(v2[1], v2[0], v2[1]); + } + bn_mul(v1[0], v2[1], v1[1]); + bn_mod(l, v1[0], v2[0]); + bn_sub(v1[1], v2[0], l); + if (bn_cmp(v1[1], l) == RLC_LT) { + bn_copy(l, v1[1]); + } + TEST_CASE("endomorphism is correct") { /* Test if \psi(P) = [l]P. */ ep_rand(a); @@ -541,6 +541,7 @@ static int endomorphism(void) { TEST_CASE("endomorphism in projective coordinates is correct") { ep_rand(a); ep_dbl_projc(a, a); + ep_norm(a, a); ep_psi(b, a); ep_mul(c, a, l); TEST_ASSERT(ep_cmp(b, c) == RLC_EQ, end); @@ -548,7 +549,7 @@ static int endomorphism(void) { TEST_END; #endif } -#endif +#endif /* EP_ENDOM */ (void)a; (void)b; (void)c; @@ -564,8 +565,8 @@ static int endomorphism(void) { ep_free(b); ep_free(c); for (int k = 0; k < 3; k++) { - bn_null(v1[k]); - bn_null(v2[k]); + bn_free(v1[k]); + bn_free(v2[k]); } return code; @@ -608,16 +609,16 @@ static int multiplication(void) { bn_rand_mod(k, n); ep_mul(q, p, k); ep_mul_gen(r, k); - //TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); + TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); bn_neg(k, k); ep_mul_gen(r, k); ep_neg(r, r); - //TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); + TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); bn_rand_mod(k, n); ep_mul_gen(q, k); bn_add(k, k, n); ep_mul_gen(r, k); - //TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); + TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); } TEST_END; #if EP_MUL == BASIC || !defined(STRIP) @@ -629,7 +630,7 @@ static int multiplication(void) { ep_mul_basic(r, p, k); TEST_ASSERT(ep_cmp(p, r) == RLC_EQ, end); ep_rand(p); - ep_mul(r, p, n); + ep_mul_basic(r, p, n); TEST_ASSERT(ep_is_infty(r), end); bn_rand_mod(k, n); ep_mul(q, p, k); @@ -656,7 +657,7 @@ static int multiplication(void) { ep_mul_slide(r, p, k); TEST_ASSERT(ep_cmp(p, r) == RLC_EQ, end); ep_rand(p); - ep_mul(r, p, n); + ep_mul_slide(r, p, n); TEST_ASSERT(ep_is_infty(r), end); bn_rand_mod(k, n); ep_mul(q, p, k); @@ -684,7 +685,7 @@ static int multiplication(void) { ep_mul_monty(r, p, k); TEST_ASSERT(ep_cmp(p, r) == RLC_EQ, end); ep_rand(p); - ep_mul(r, p, n); + ep_mul_monty(r, p, n); TEST_ASSERT(ep_is_infty(r), end); bn_rand_mod(k, n); ep_mul(q, p, k); @@ -712,7 +713,7 @@ static int multiplication(void) { ep_mul_lwnaf(r, p, k); TEST_ASSERT(ep_cmp(p, r) == RLC_EQ, end); ep_rand(p); - ep_mul(r, p, n); + ep_mul_lwnaf(r, p, n); TEST_ASSERT(ep_is_infty(r), end); bn_rand_mod(k, n); ep_mul(q, p, k); @@ -740,7 +741,7 @@ static int multiplication(void) { ep_mul_lwreg(r, p, k); TEST_ASSERT(ep_cmp(p, r) == RLC_EQ, end); ep_rand(p); - ep_mul(r, p, n); + ep_mul_lwreg(r, p, n); TEST_ASSERT(ep_is_infty(r), end); bn_rand_mod(k, n); ep_mul(q, p, k); @@ -759,7 +760,7 @@ static int multiplication(void) { TEST_END; #endif - TEST_CASE("multiplication by digit is correct") { + TEST_CASE("point multiplication by digit is correct") { ep_mul_dig(r, p, 0); TEST_ASSERT(ep_is_infty(r), end); ep_mul_dig(r, p, 1); @@ -831,6 +832,11 @@ static int fixed(void) { ep_mul_fix(r, (const ep_t *)t, k); ep_neg(r, r); TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep_mul_fix(q, (const ep_t *)t, k); + bn_add(k, k, n); + ep_mul_fix(r, (const ep_t *)t, k); + TEST_ASSERT(ep_cmp(q, r) == RLC_EQ, end); } TEST_END; for (int i = 0; i < RLC_EP_TABLE; i++) { ep_free(t[i]); @@ -980,23 +986,21 @@ static int fixed(void) { static int simultaneous(void) { int code = RLC_ERR; - bn_t n, k[2]; - ep_t p[2], r; + bn_t n, k[17]; + ep_t p[17], r; bn_null(n); - bn_null(k[0]); - bn_null(k[1]); - ep_null(p[0]); - ep_null(p[1]); ep_null(r); RLC_TRY { bn_new(n); - bn_new(k[0]); - bn_new(k[1]); - ep_new(p[0]); - ep_new(p[1]); ep_new(r); + for (int i = 0; i <= 16; i++) { + bn_null(k[i]); + bn_new(k[i]); + ep_null(p[i]); + ep_new(p[i]); + } ep_curve_get_gen(p[0]); ep_curve_get_ord(n); @@ -1031,9 +1035,6 @@ static int simultaneous(void) { ep_mul(p[1], p[1], k[1]); ep_add(p[1], p[1], p[0]); TEST_ASSERT(ep_cmp(p[1], r) == RLC_EQ, end); - ep_mul_sim(r, p[0], k[0], p[1], k[1]); - ep_mul_sim_lot(p[1], p, k, 2); - TEST_ASSERT(ep_cmp(p[1], r) == RLC_EQ, end); bn_rand_mod(k[0], n); bn_rand_mod(k[1], n); bn_add(k[0], k[0], n); @@ -1043,6 +1044,9 @@ static int simultaneous(void) { ep_mul(p[1], p[1], k[1]); ep_add(p[1], p[1], p[0]); TEST_ASSERT(ep_cmp(p[1], r) == RLC_EQ, end); + ep_mul_sim(r, p[0], k[0], p[1], k[1]); + ep_mul_sim_lot(p[1], p, k, 2); + TEST_ASSERT(ep_cmp(p[1], r) == RLC_EQ, end); } TEST_END; #if EP_SIM == BASIC || !defined(STRIP) @@ -1253,6 +1257,34 @@ static int simultaneous(void) { ep_mul_sim(p[1], p[0], k[0], p[1], k[1]); TEST_ASSERT(ep_cmp(p[1], r) == RLC_EQ, end); } TEST_END; + + TEST_CASE("many simultaneous point multiplications are correct") { + ep_set_infty(r); + ep_mul_sim_lot(p[16], p, k, 0); + TEST_ASSERT(ep_cmp(p[16], r) == RLC_EQ, end); + for (int j = 0; j < 16; j++) { + bn_rand_mod(k[j], n); + ep_rand(p[j]); + ep_mul(p[16], p[j], k[j]); + ep_add(r, r, p[16]); + ep_mul_sim_lot(p[16], p, k, j + 1); + TEST_ASSERT(ep_cmp(p[16], r) == RLC_EQ, end); + } + ep_mul(p[16], p[0], k[0]); + ep_sub(r, r, p[16]); + bn_zero(k[0]); + ep_mul_sim_lot(p[16], p, k, 16); + TEST_ASSERT(ep_cmp(p[16], r) == RLC_EQ, end); + ep_mul(p[16], p[1], k[1]); + ep_sub(r, r, p[16]); + ep_sub(r, r, p[16]); + bn_neg(k[1], k[1]); + ep_mul_sim_lot(p[16], p, k, 16); + TEST_ASSERT(ep_cmp(p[16], r) == RLC_EQ, end); + bn_add(k[2], k[2], n); + ep_mul_sim_lot(p[16], p, k, 16); + TEST_ASSERT(ep_cmp(p[16], r) == RLC_EQ, end); + } TEST_END; } RLC_CATCH_ANY { util_print("FATAL ERROR!\n"); @@ -1261,10 +1293,10 @@ static int simultaneous(void) { code = RLC_OK; end: bn_free(n); - bn_free(k[0]); - bn_free(k[1]); - ep_free(p[0]); - ep_free(p[1]); + for (int i = 0; i <= 16; i++) { + bn_free(k[i]); + ep_free(p[i]); + } ep_free(r); return code; } diff --git a/contrib/relic/test/test_epx.c b/contrib/relic/test/test_epx.c index 574f53aed..34b5d8a18 100644 --- a/contrib/relic/test/test_epx.c +++ b/contrib/relic/test/test_epx.c @@ -34,7 +34,7 @@ #include "relic.h" #include "relic_test.h" -static int memory(void) { +static int memory2(void) { err_t e; int code = RLC_ERR; ep2_t a; @@ -60,7 +60,7 @@ static int memory(void) { return code; } -static int util(void) { +static int util2(void) { int l, code = RLC_ERR; ep2_t a, b, c; uint8_t bin[4 * RLC_FP_BYTES + 1]; @@ -179,7 +179,7 @@ static int util(void) { return code; } -static int addition(void) { +static int addition2(void) { int code = RLC_ERR; ep2_t a, b, c, d, e; @@ -295,7 +295,7 @@ static int addition(void) { return code; } -static int subtraction(void) { +static int subtraction2(void) { int code = RLC_ERR; ep2_t a, b, c, d; @@ -347,7 +347,7 @@ static int subtraction(void) { return code; } -static int doubling(void) { +static int doubling2(void) { int code = RLC_ERR; ep2_t a, b, c; @@ -407,7 +407,7 @@ static int doubling(void) { return code; } -static int multiplication(void) { +static int multiplication2(void) { int code = RLC_ERR; bn_t n, k; ep2_t p, q, r; @@ -449,6 +449,11 @@ static int multiplication(void) { ep2_mul_gen(r, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_gen(q, k); + bn_add(k, k, n); + ep2_mul_gen(r, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; #if EP_MUL == BASIC || !defined(STRIP) @@ -460,7 +465,7 @@ static int multiplication(void) { ep2_mul_basic(r, p, k); TEST_ASSERT(ep2_cmp(p, r) == RLC_EQ, end); ep2_rand(p); - ep2_mul(r, p, n); + ep2_mul_basic(r, p, n); TEST_ASSERT(ep2_is_infty(r), end); bn_rand_mod(k, n); ep2_mul(q, p, k); @@ -470,6 +475,11 @@ static int multiplication(void) { ep2_mul_basic(r, p, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_basic(q, p, k); + bn_add(k, k, n); + ep2_mul_basic(r, p, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; #endif @@ -482,7 +492,7 @@ static int multiplication(void) { ep2_mul_slide(r, p, k); TEST_ASSERT(ep2_cmp(p, r) == RLC_EQ, end); ep2_rand(p); - ep2_mul(r, p, n); + ep2_mul_slide(r, p, n); TEST_ASSERT(ep2_is_infty(r), end); bn_rand_mod(k, n); ep2_mul(q, p, k); @@ -492,6 +502,11 @@ static int multiplication(void) { ep2_mul_slide(r, p, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_slide(q, p, k); + bn_add(k, k, n); + ep2_mul_slide(r, p, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; #endif @@ -505,7 +520,7 @@ static int multiplication(void) { ep2_mul_monty(r, p, k); TEST_ASSERT(ep2_cmp(p, r) == RLC_EQ, end); ep2_rand(p); - ep2_mul(r, p, n); + ep2_mul_monty(r, p, n); TEST_ASSERT(ep2_is_infty(r), end); bn_rand_mod(k, n); ep2_mul(q, p, k); @@ -515,6 +530,11 @@ static int multiplication(void) { ep2_mul_monty(r, p, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_monty(q, p, k); + bn_add(k, k, n); + ep2_mul_monty(r, p, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; #endif @@ -528,7 +548,7 @@ static int multiplication(void) { ep2_mul_lwnaf(r, p, k); TEST_ASSERT(ep2_cmp(p, r) == RLC_EQ, end); ep2_rand(p); - ep2_mul(r, p, n); + ep2_mul_lwnaf(r, p, n); TEST_ASSERT(ep2_is_infty(r), end); bn_rand_mod(k, n); ep2_mul(q, p, k); @@ -538,11 +558,16 @@ static int multiplication(void) { ep2_mul_lwnaf(r, p, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_lwnaf(q, p, k); + bn_add(k, k, n); + ep2_mul_lwnaf(r, p, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; #endif - TEST_CASE("multiplication by digit is correct") { + TEST_CASE("point multiplication by digit is correct") { ep2_mul_dig(r, p, 0); TEST_ASSERT(ep2_is_infty(r), end); ep2_mul_dig(r, p, 1); @@ -568,7 +593,7 @@ static int multiplication(void) { return code; } -static int fixed(void) { +static int fixed2(void) { int code = RLC_ERR; bn_t n, k; ep2_t p, q, r, t[RLC_EPX_TABLE_MAX]; @@ -614,6 +639,11 @@ static int fixed(void) { ep2_mul_fix(r, t, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_fix(q, t, k); + bn_add(k, k, n); + ep2_mul_fix(r, t, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; for (int i = 0; i < RLC_EP_TABLE; i++) { ep2_free(t[i]); @@ -640,6 +670,11 @@ static int fixed(void) { ep2_mul_fix_basic(r, t, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_fix_basic(q, t, k); + bn_add(k, k, n); + ep2_mul_fix_basic(r, t, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; for (int i = 0; i < RLC_EP_TABLE_BASIC; i++) { ep2_free(t[i]); @@ -667,6 +702,11 @@ static int fixed(void) { ep2_mul_fix_combs(r, t, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_fix_combs(q, t, k); + bn_add(k, k, n); + ep2_mul_fix_combs(r, t, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; for (int i = 0; i < RLC_EP_TABLE_COMBS; i++) { ep2_free(t[i]); @@ -694,6 +734,11 @@ static int fixed(void) { ep2_mul_fix_combd(r, t, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_fix_combd(q, t, k); + bn_add(k, k, n); + ep2_mul_fix_combd(r, t, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; for (int i = 0; i < RLC_EP_TABLE_COMBD; i++) { ep2_free(t[i]); @@ -721,6 +766,11 @@ static int fixed(void) { ep2_mul_fix_lwnaf(r, t, k); ep2_neg(r, r); TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_fix_lwnaf(q, t, k); + bn_add(k, k, n); + ep2_mul_fix_lwnaf(r, t, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); } TEST_END; for (int i = 0; i < RLC_EP_TABLE_LWNAF; i++) { ep2_free(t[i]); @@ -741,25 +791,22 @@ static int fixed(void) { return code; } -static int simultaneous(void) { +static int simultaneous2(void) { int code = RLC_ERR; - bn_t n, k[2]; - ep2_t p[2], r; + bn_t n, k[17]; + ep2_t p[17], r; bn_null(n); - bn_null(k[0]); - bn_null(k[1]); - ep2_null(p[0]); - ep2_null(p[1]); ep2_null(r); - RLC_TRY { bn_new(n); - bn_new(k[0]); - bn_new(k[1]); - ep2_new(p[0]); - ep2_new(p[1]); ep2_new(r); + for (int i = 0; i <= 16; i++) { + bn_null(k[i]); + bn_new(k[i]); + ep2_null(p[i]); + ep2_new(p[i]); + } ep2_curve_get_gen(p[0]); ep2_curve_get_ord(n); @@ -794,6 +841,15 @@ static int simultaneous(void) { ep2_mul(p[1], p[1], k[1]); ep2_add(p[1], p[1], p[0]); TEST_ASSERT(ep2_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + bn_add(k[0], k[0], n); + bn_add(k[1], k[1], n); + ep2_mul_sim(r, p[0], k[0], p[1], k[1]); + ep2_mul(p[0], p[0], k[0]); + ep2_mul(p[1], p[1], k[1]); + ep2_add(p[1], p[1], p[0]); + TEST_ASSERT(ep2_cmp(p[1], r) == RLC_EQ, end); ep2_mul_sim(r, p[0], k[0], p[1], k[1]); ep2_mul_sim_lot(p[1], p, k, 2); TEST_ASSERT(ep2_cmp(p[1], r) == RLC_EQ, end); @@ -963,6 +1019,32 @@ static int simultaneous(void) { ep2_mul_sim(p[1], p[0], k[0], p[1], k[1]); TEST_ASSERT(ep2_cmp(p[1], r) == RLC_EQ, end); } TEST_END; + + TEST_CASE("many simultaneous point multiplications are correct") { + ep2_set_infty(r); + for (int j = 0; j < 16; j++) { + bn_rand_mod(k[j], n); + ep2_rand(p[j]); + ep2_mul(p[16], p[j], k[j]); + ep2_add(r, r, p[16]); + ep2_mul_sim_lot(p[16], p, k, j + 1); + TEST_ASSERT(ep2_cmp(p[16], r) == RLC_EQ, end); + } + ep2_mul(p[16], p[0], k[0]); + ep2_sub(r, r, p[16]); + bn_zero(k[0]); + ep2_mul_sim_lot(p[16], p, k, 16); + TEST_ASSERT(ep2_cmp(p[16], r) == RLC_EQ, end); + ep2_mul(p[16], p[1], k[1]); + ep2_sub(r, r, p[16]); + ep2_sub(r, r, p[16]); + bn_neg(k[1], k[1]); + ep2_mul_sim_lot(p[16], p, k, 16); + TEST_ASSERT(ep2_cmp(p[16], r) == RLC_EQ, end); + bn_add(k[2], k[2], n); + ep2_mul_sim_lot(p[16], p, k, 16); + TEST_ASSERT(ep2_cmp(p[16], r) == RLC_EQ, end); + } TEST_END; } RLC_CATCH_ANY { util_print("FATAL ERROR!\n"); @@ -971,15 +1053,15 @@ static int simultaneous(void) { code = RLC_OK; end: bn_free(n); - bn_free(k[0]); - bn_free(k[1]); - ep2_free(p[0]); - ep2_free(p[1]); ep2_free(r); + for (int i = 0; i <= 16; i++) { + bn_free(k[i]); + ep2_free(p[i]); + } return code; } -static int compression(void) { +static int compression2(void) { int code = RLC_ERR; ep2_t a, b, c; @@ -1011,7 +1093,7 @@ static int compression(void) { return code; } -static int hashing(void) { +static int hashing2(void) { int code = RLC_ERR; bn_t n; ep2_t p; @@ -1052,7 +1134,7 @@ static int hashing(void) { return code; } -static int frobenius(void) { +static int frobenius2(void) { int code = RLC_ERR; ep2_t a, b, c; bn_t d, n; @@ -1072,7 +1154,7 @@ static int frobenius(void) { ep2_curve_get_ord(n); - TEST_CASE("frobenius and scalar multiplication are consistent") { + TEST_CASE("frobenius and point multiplication are consistent") { ep2_rand(a); ep2_frb(b, a, 1); d->used = RLC_FP_DIGS; @@ -1096,85 +1178,1169 @@ static int frobenius(void) { return code; } -int main(void) { - if (core_init() != RLC_OK) { - core_clean(); - return 1; - } +static int memory4(void) { + err_t e; + int code = RLC_ERR; + ep4_t a; - util_banner("Tests for the EPX module", 0); + ep4_null(a); - if (ep_param_set_any_pairf() == RLC_ERR) { - RLC_THROW(ERR_NO_CURVE); - core_clean(); - return 0; + RLC_TRY { + TEST_CASE("memory can be allocated") { + ep4_new(a); + ep4_free(a); + } TEST_END; + } RLC_CATCH(e) { + switch (e) { + case ERR_NO_MEMORY: + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + break; + } } + (void)a; + code = RLC_OK; + end: + return code; +} - if (ep2_curve_is_twist() == 0) { - RLC_THROW(ERR_NO_CURVE); - core_clean(); - return 0; - } +static int util4(void) { + int l, code = RLC_ERR; + ep4_t a, b, c; + uint8_t bin[8 * RLC_FP_BYTES + 1]; - ep_param_print(); + ep4_null(a); + ep4_null(b); + ep4_null(c); - util_banner("Utilities:", 1); + RLC_TRY { + ep4_new(a); + ep4_new(b); + ep4_new(c); - if (memory() != RLC_OK) { - core_clean(); - return 1; - } + TEST_CASE("copy and comparison are consistent") { + ep4_rand(a); + ep4_rand(b); + ep4_rand(c); + /* Compare points in affine coordinates. */ + if (ep4_cmp(a, c) != RLC_EQ) { + ep4_copy(c, a); + TEST_ASSERT(ep4_cmp(c, a) == RLC_EQ, end); + } + if (ep4_cmp(b, c) != RLC_EQ) { + ep4_copy(c, b); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } + /* Compare with one point in projective. */ + ep4_dbl(c, a); + ep4_norm(c, c); + ep4_dbl(a, a); + TEST_ASSERT(ep4_cmp(c, a) == RLC_EQ, end); + TEST_ASSERT(ep4_cmp(a, c) == RLC_EQ, end); + /* Compare with two points in projective. */ + ep4_dbl(c, c); + ep4_dbl(a, a); + TEST_ASSERT(ep4_cmp(c, a) == RLC_EQ, end); + TEST_ASSERT(ep4_cmp(a, c) == RLC_EQ, end); + } + TEST_END; - if (util() != RLC_OK) { - core_clean(); - return 1; - } + TEST_CASE("negation and comparison are consistent") { + ep4_rand(a); + ep4_neg(b, a); + TEST_ASSERT(ep4_cmp(a, b) != RLC_EQ, end); + ep4_neg(b, b); + TEST_ASSERT(ep4_cmp(a, b) == RLC_EQ, end); + ep4_neg(b, a); + ep4_add(a, a, b); + ep4_set_infty(b); + TEST_ASSERT(ep4_cmp(a, b) == RLC_EQ, end); + } + TEST_END; - util_banner("Arithmetic:", 1); + TEST_CASE("assignment to random and comparison are consistent") { + ep4_rand(a); + ep4_set_infty(c); + TEST_ASSERT(ep4_cmp(a, c) != RLC_EQ, end); + TEST_ASSERT(ep4_cmp(c, a) != RLC_EQ, end); + } + TEST_END; - if (addition() != RLC_OK) { - core_clean(); - return 1; - } + TEST_CASE("assignment to infinity and infinity test are consistent") { + ep4_set_infty(a); + TEST_ASSERT(ep4_is_infty(a), end); + } + TEST_END; - if (subtraction() != RLC_OK) { - core_clean(); - return 1; - } + TEST_CASE("validity test is correct") { + ep4_set_infty(a); + TEST_ASSERT(ep4_on_curve(a), end); + ep4_rand(a); + TEST_ASSERT(ep4_on_curve(a), end); + fp4_rand(a->x); + TEST_ASSERT(!ep4_on_curve(a), end); + } + TEST_END; - if (doubling() != RLC_OK) { - core_clean(); - return 1; - } + TEST_CASE("blinding is consistent") { + ep4_rand(a); + ep4_blind(a, a); + TEST_ASSERT(ep4_on_curve(a), end); + } TEST_END; - if (multiplication() != RLC_OK) { - core_clean(); - return 1; + TEST_CASE("reading and writing a point are consistent") { + ep4_set_infty(a); + l = ep4_size_bin(a, 0); + ep4_write_bin(bin, l, a, 0); + ep4_read_bin(b, bin, l); + TEST_ASSERT(ep4_cmp(a, b) == RLC_EQ, end); + ep4_rand(a); + l = ep4_size_bin(a, 0); + ep4_write_bin(bin, l, a, 0); + ep4_read_bin(b, bin, l); + TEST_ASSERT(ep4_cmp(a, b) == RLC_EQ, end); + ep4_rand(a); + ep4_dbl(a, a); + l = ep4_size_bin(a, 0); + ep4_norm(a, a); + ep4_write_bin(bin, l, a, 0); + ep4_read_bin(b, bin, l); + TEST_ASSERT(ep4_cmp(a, b) == RLC_EQ, end); + } + TEST_END; } - - if (fixed() != RLC_OK) { - core_clean(); - return 1; + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); } + code = RLC_OK; + end: + ep4_free(a); + ep4_free(b); + ep4_free(c); + return code; +} - if (simultaneous() != RLC_OK) { - core_clean(); - return 1; +static int addition4(void) { + int code = RLC_ERR; + ep4_t a, b, c, d, e; + + ep4_null(a); + ep4_null(b); + ep4_null(c); + ep4_null(d); + ep4_null(e); + + RLC_TRY { + ep4_new(a); + ep4_new(b); + ep4_new(c); + ep4_new(d); + ep4_new(e); + + TEST_CASE("point addition is commutative") { + ep4_rand(a); + ep4_rand(b); + ep4_add(d, a, b); + ep4_add(e, b, a); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition is associative") { + ep4_rand(a); + ep4_rand(b); + ep4_rand(c); + ep4_add(d, a, b); + ep4_add(d, d, c); + ep4_add(e, b, c); + ep4_add(e, e, a); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition has identity") { + ep4_rand(a); + ep4_set_infty(d); + ep4_add(e, a, d); + TEST_ASSERT(ep4_cmp(e, a) == RLC_EQ, end); + ep4_add(e, d, a); + TEST_ASSERT(ep4_cmp(e, a) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition has inverse") { + ep4_rand(a); + ep4_neg(d, a); + ep4_add(e, a, d); + TEST_ASSERT(ep4_is_infty(e), end); + } TEST_END; + +#if EP_ADD == BASIC || !defined(STRIP) + TEST_CASE("point addition in affine coordinates is correct") { + ep4_rand(a); + ep4_rand(b); + ep4_add(d, a, b); + ep4_add_basic(e, a, b); + TEST_ASSERT(ep4_cmp(e, d) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_ADD == PROJC || !defined(STRIP) +#if !defined(EP_MIXED) || !defined(STRIP) + TEST_CASE("point addition in projective coordinates is correct") { + ep4_rand(a); + ep4_rand(b); + ep4_rand(c); + ep4_add_projc(a, a, b); + ep4_add_projc(b, b, c); + /* a and b in projective coordinates. */ + ep4_add_projc(d, a, b); + /* normalize before mixing coordinates. */ + ep4_norm(a, a); + ep4_norm(b, b); + ep4_add(e, a, b); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("point addition in mixed coordinates (z2 = 1) is correct") { + ep4_rand(a); + ep4_rand(b); + /* a in projective, b in affine coordinates. */ + ep4_add_projc(a, a, b); + ep4_add_projc(d, a, b); + /* a in affine coordinates. */ + ep4_norm(a, a); + ep4_add(e, a, b); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition in mixed coordinates (z1,z2 = 1) is correct") { + ep4_rand(a); + ep4_rand(b); + /* a and b in affine coordinates. */ + ep4_add(d, a, b); + ep4_add_projc(e, a, b); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif + + } + RLC_CATCH_ANY { + RLC_ERROR(end); } + code = RLC_OK; + end: + ep4_free(a); + ep4_free(b); + ep4_free(c); + ep4_free(d); + ep4_free(e); + return code; +} - if (compression() != RLC_OK) { - core_clean(); - return 1; +static int subtraction4(void) { + int code = RLC_ERR; + ep4_t a, b, c, d; + + ep4_null(a); + ep4_null(b); + ep4_null(c); + ep4_null(d); + + RLC_TRY { + ep4_new(a); + ep4_new(b); + ep4_new(c); + ep4_new(d); + + TEST_CASE("point subtraction is anti-commutative") { + ep4_rand(a); + ep4_rand(b); + ep4_sub(c, a, b); + ep4_sub(d, b, a); + ep4_neg(d, d); + TEST_ASSERT(ep4_cmp(c, d) == RLC_EQ, end); + } + TEST_END; + + TEST_CASE("point subtraction has identity") { + ep4_rand(a); + ep4_set_infty(c); + ep4_sub(d, a, c); + TEST_ASSERT(ep4_cmp(d, a) == RLC_EQ, end); + } + TEST_END; + + TEST_CASE("point subtraction has inverse") { + ep4_rand(a); + ep4_sub(c, a, a); + TEST_ASSERT(ep4_is_infty(c), end); + } + TEST_END; + } + RLC_CATCH_ANY { + RLC_ERROR(end); } + code = RLC_OK; + end: + ep4_free(a); + ep4_free(b); + ep4_free(c); + ep4_free(d); + return code; +} - if (hashing() != RLC_OK) { - core_clean(); - return 1; +static int doubling4(void) { + int code = RLC_ERR; + ep4_t a, b, c; + + ep4_null(a); + ep4_null(b); + ep4_null(c); + + RLC_TRY { + ep4_new(a); + ep4_new(b); + ep4_new(c); + + TEST_CASE("point doubling is correct") { + ep4_rand(a); + ep4_add(b, a, a); + ep4_dbl(c, a); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } TEST_END; + +#if EP_ADD == BASIC || !defined(STRIP) + TEST_CASE("point doubling in affine coordinates is correct") { + ep4_rand(a); + ep4_dbl(b, a); + ep4_dbl_basic(c, a); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_ADD == PROJC || !defined(STRIP) + TEST_CASE("point doubling in projective coordinates is correct") { + ep4_rand(a); + /* a in projective coordinates. */ + ep4_dbl_projc(a, a); + ep4_dbl_projc(b, a); + ep4_norm(a, a); + ep4_dbl(c, a); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point doubling in mixed coordinates (z1 = 1) is correct") { + ep4_rand(a); + ep4_dbl_projc(b, a); + ep4_norm(b, b); + ep4_dbl(c, a); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + end: + ep4_free(a); + ep4_free(b); + ep4_free(c); + return code; +} - if (frobenius() != RLC_OK) { - core_clean(); - return 1; +static int multiplication4(void) { + int code = RLC_ERR; + bn_t n, k; + ep4_t p, q, r; + + bn_null(n); + bn_null(k); + ep4_null(p); + ep4_null(q); + ep4_null(r); + + RLC_TRY { + bn_new(n); + bn_new(k); + ep4_new(p); + ep4_new(q); + ep4_new(r); + + ep4_curve_get_gen(p); + ep4_curve_get_ord(n); + + TEST_ONCE("generator has the right order") { + TEST_ASSERT(ep4_on_curve(p), end); + ep4_mul(r, p, n); + TEST_ASSERT(ep4_is_infty(r) == 1, end); + } TEST_END; + + TEST_CASE("generator multiplication is correct") { + bn_zero(k); + ep4_mul_gen(r, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_gen(r, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_gen(r, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_gen(r, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; + +#if EP_MUL == BASIC || !defined(STRIP) + TEST_CASE("binary point multiplication is correct") { + bn_zero(k); + ep4_mul_basic(r, p, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_basic(r, p, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + ep4_rand(p); + ep4_mul(r, p, n); + TEST_ASSERT(ep4_is_infty(r), end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_basic(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_basic(r, p, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_MUL == MONTY || !defined(STRIP) + TEST_CASE("sliding window point multiplication is correct") { + bn_zero(k); + ep4_mul_slide(r, p, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_slide(r, p, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + ep4_rand(p); + ep4_mul(r, p, n); + TEST_ASSERT(ep4_is_infty(r), end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_slide(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_slide(r, p, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + +#if EP_MUL == MONTY || !defined(STRIP) + TEST_CASE("montgomery ladder point multiplication is correct") { + bn_zero(k); + ep4_mul_monty(r, p, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_monty(r, p, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + ep4_rand(p); + ep4_mul(r, p, n); + TEST_ASSERT(ep4_is_infty(r), end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_monty(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_monty(r, p, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + +#if EP_MUL == LWNAF || !defined(STRIP) + TEST_CASE("left-to-right w-naf point multiplication is correct") { + bn_zero(k); + ep4_mul_lwnaf(r, p, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_lwnaf(r, p, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + ep4_rand(p); + ep4_mul(r, p, n); + TEST_ASSERT(ep4_is_infty(r), end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_lwnaf(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_lwnaf(r, p, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + + TEST_CASE("multiplication by digit is correct") { + ep4_mul_dig(r, p, 0); + TEST_ASSERT(ep4_is_infty(r), end); + ep4_mul_dig(r, p, 1); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand(k, RLC_POS, RLC_DIG); + ep4_mul(q, p, k); + ep4_mul_dig(r, p, k->dp[0]); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } + TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(n); + bn_free(k); + ep4_free(p); + ep4_free(q); + ep4_free(r); + return code; +} + +static int fixed4(void) { + int code = RLC_ERR; + bn_t n, k; + ep4_t p, q, r, t[RLC_EPX_TABLE_MAX]; + + bn_null(n); + bn_null(k); + ep4_null(p); + ep4_null(q); + ep4_null(r); + + for (int i = 0; i < RLC_EPX_TABLE_MAX; i++) { + ep4_null(t[i]); + } + + RLC_TRY { + bn_new(n); + bn_new(k); + ep4_new(p); + ep4_new(q); + ep4_new(r); + + ep4_curve_get_gen(p); + ep4_curve_get_ord(n); + + for (int i = 0; i < RLC_EP_TABLE; i++) { + ep4_new(t[i]); + } + TEST_CASE("fixed point multiplication is correct") { + ep4_rand(p); + ep4_mul_pre(t, p); + bn_zero(k); + ep4_mul_fix(r, t, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_fix(r, t, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_fix(q, t, k); + ep4_mul(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_fix(r, t, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; + for (int i = 0; i < RLC_EP_TABLE; i++) { + ep4_free(t[i]); + } + +#if EP_FIX == BASIC || !defined(STRIP) + for (int i = 0; i < RLC_EP_TABLE_BASIC; i++) { + ep4_new(t[i]); + } + TEST_CASE("binary fixed point multiplication is correct") { + ep4_rand(p); + ep4_mul_pre_basic(t, p); + bn_zero(k); + ep4_mul_fix_basic(r, t, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_fix_basic(r, t, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul(r, p, k); + ep4_mul_fix_basic(q, t, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_fix_basic(r, t, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; + for (int i = 0; i < RLC_EP_TABLE_BASIC; i++) { + ep4_free(t[i]); + } +#endif + +#if EP_FIX == COMBS || !defined(STRIP) + for (int i = 0; i < RLC_EP_TABLE_COMBS; i++) { + ep4_new(t[i]); + } + TEST_CASE("single-table comb fixed point multiplication is correct") { + ep4_rand(p); + ep4_mul_pre_combs(t, p); + bn_zero(k); + ep4_mul_fix_combs(r, t, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_fix_combs(r, t, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul(r, p, k); + ep4_mul_fix_combs(q, t, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_fix_combs(r, t, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; + for (int i = 0; i < RLC_EP_TABLE_COMBS; i++) { + ep4_free(t[i]); + } +#endif + +#if EP_FIX == COMBD || !defined(STRIP) + for (int i = 0; i < RLC_EP_TABLE_COMBD; i++) { + ep4_new(t[i]); + } + TEST_CASE("double-table comb fixed point multiplication is correct") { + ep4_rand(p); + ep4_mul_pre_combd(t, p); + bn_zero(k); + ep4_mul_fix_combd(r, t, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_fix_combd(r, t, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul(r, p, k); + ep4_mul_fix_combd(q, t, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_fix_combd(r, t, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; + for (int i = 0; i < RLC_EP_TABLE_COMBD; i++) { + ep4_free(t[i]); + } +#endif + +#if EP_FIX == LWNAF || !defined(STRIP) + for (int i = 0; i < RLC_EP_TABLE_LWNAF; i++) { + ep4_new(t[i]); + } + TEST_CASE("left-to-right w-naf fixed point multiplication is correct") { + ep4_rand(p); + ep4_mul_pre_lwnaf(t, p); + bn_zero(k); + ep4_mul_fix_lwnaf(r, t, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_fix_lwnaf(r, t, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul(r, p, k); + ep4_mul_fix_lwnaf(q, t, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_fix_lwnaf(r, t, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } TEST_END; + for (int i = 0; i < RLC_EP_TABLE_LWNAF; i++) { + ep4_free(t[i]); + } +#endif + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + ep4_free(p); + ep4_free(q); + ep4_free(r); + bn_free(n); + bn_free(k); + return code; +} + +static int simultaneous4(void) { + int code = RLC_ERR; + bn_t n, k[2]; + ep4_t p[2], r; + + bn_null(n); + bn_null(k[0]); + bn_null(k[1]); + ep4_null(p[0]); + ep4_null(p[1]); + ep4_null(r); + + RLC_TRY { + bn_new(n); + bn_new(k[0]); + bn_new(k[1]); + ep4_new(p[0]); + ep4_new(p[1]); + ep4_new(r); + + ep4_curve_get_gen(p[0]); + ep4_curve_get_ord(n); + + TEST_CASE("simultaneous point multiplication is correct") { + bn_zero(k[0]); + bn_rand_mod(k[1], n); + ep4_mul(p[1], p[0], k[1]); + ep4_mul_sim(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_zero(k[1]); + ep4_mul(p[1], p[0], k[0]); + ep4_mul_sim(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + ep4_mul_sim(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[0], k[0]); + ep4_mul_sim(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[1], k[1]); + ep4_mul_sim(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + ep4_mul_sim(r, p[0], k[0], p[1], k[1]); + ep4_mul_sim_lot(p[1], p, k, 2); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + } TEST_END; + +#if EP_SIM == BASIC || !defined(STRIP) + TEST_CASE("basic simultaneous point multiplication is correct") { + bn_zero(k[0]); + bn_rand_mod(k[1], n); + ep4_mul(p[1], p[0], k[1]); + ep4_mul_sim_basic(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_zero(k[1]); + ep4_mul(p[1], p[0], k[0]); + ep4_mul_sim_basic(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + ep4_mul_sim_basic(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[0], k[0]); + ep4_mul_sim_basic(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[1], k[1]); + ep4_mul_sim_basic(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_SIM == TRICK || !defined(STRIP) + TEST_CASE("shamir's trick for simultaneous multiplication is correct") { + bn_zero(k[0]); + bn_rand_mod(k[1], n); + ep4_mul(p[1], p[0], k[1]); + ep4_mul_sim_trick(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_zero(k[1]); + ep4_mul(p[1], p[0], k[0]); + ep4_mul_sim_trick(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + ep4_mul_sim_trick(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[0], k[0]); + ep4_mul_sim_trick(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[1], k[1]); + ep4_mul_sim_trick(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_SIM == INTER || !defined(STRIP) + TEST_CASE("interleaving for simultaneous multiplication is correct") { + bn_zero(k[0]); + bn_rand_mod(k[1], n); + ep4_mul(p[1], p[0], k[1]); + ep4_mul_sim_inter(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_zero(k[1]); + ep4_mul(p[1], p[0], k[0]); + ep4_mul_sim_inter(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + ep4_mul_sim_inter(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[0], k[0]); + ep4_mul_sim_inter(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[1], k[1]); + ep4_mul_sim_inter(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_SIM == JOINT || !defined(STRIP) + TEST_CASE("jsf for simultaneous multiplication is correct") { + bn_zero(k[0]); + bn_rand_mod(k[1], n); + ep4_mul(p[1], p[0], k[1]); + ep4_mul_sim_joint(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_zero(k[1]); + ep4_mul(p[1], p[0], k[0]); + ep4_mul_sim_joint(r, p[0], k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + ep4_mul_sim_joint(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[0], k[0]); + ep4_mul_sim_joint(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[1], k[1]); + ep4_mul_sim_joint(r, p[0], k[0], p[1], k[1]); + ep4_mul(p[0], p[0], k[0]); + ep4_mul(p[1], p[1], k[1]); + ep4_add(p[1], p[1], p[0]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("simultaneous multiplication with generator is correct") { + bn_zero(k[0]); + bn_rand_mod(k[1], n); + ep4_mul(p[1], p[0], k[1]); + ep4_mul_sim_gen(r, k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_zero(k[1]); + ep4_mul_gen(p[1], k[0]); + ep4_mul_sim_gen(r, k[0], p[0], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_rand_mod(k[0], n); + bn_rand_mod(k[1], n); + ep4_mul_sim_gen(r, k[0], p[1], k[1]); + ep4_curve_get_gen(p[0]); + ep4_mul_sim(p[1], p[0], k[0], p[1], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[0], k[0]); + ep4_mul_sim_gen(r, k[0], p[1], k[1]); + ep4_curve_get_gen(p[0]); + ep4_mul_sim(p[1], p[0], k[0], p[1], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + bn_neg(k[1], k[1]); + ep4_mul_sim_gen(r, k[0], p[1], k[1]); + ep4_curve_get_gen(p[0]); + ep4_mul_sim(p[1], p[0], k[0], p[1], k[1]); + TEST_ASSERT(ep4_cmp(p[1], r) == RLC_EQ, end); + } TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(n); + bn_free(k[0]); + bn_free(k[1]); + ep4_free(p[0]); + ep4_free(p[1]); + ep4_free(r); + return code; +} + +static int hashing4(void) { + int code = RLC_ERR; + bn_t n; + ep4_t p; + uint8_t msg[5]; + + bn_null(n); + ep4_null(p); + + RLC_TRY { + bn_new(n); + ep4_new(p); + + ep4_curve_get_ord(n); + + TEST_CASE("point hashing is correct") { + rand_bytes(msg, sizeof(msg)); + ep4_map(p, msg, sizeof(msg)); + TEST_ASSERT(ep4_is_infty(p) == 0, end); + ep4_mul(p, p, n); + TEST_ASSERT(ep4_is_infty(p) == 1, end); + } + TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(n); + ep4_free(p); + return code; +} + +static int frobenius4(void) { + int code = RLC_ERR; + ep4_t a, b, c; + bn_t d, n; + + ep4_null(a); + ep4_null(b); + ep4_null(c); + bn_null(d); + bn_null(n); + + RLC_TRY { + ep4_new(a); + ep4_new(b); + ep4_new(c); + bn_new(d); + bn_new(n); + + ep4_curve_get_ord(n); + + TEST_CASE("frobenius and point multiplication are consistent") { + ep4_rand(a); + ep4_frb(b, a, 1); + d->used = RLC_FP_DIGS; + dv_copy(d->dp, fp_prime_get(), RLC_FP_DIGS); + bn_mod(d, d, n); + ep4_mul(c, a, d); + TEST_ASSERT(ep4_cmp(c, b) == RLC_EQ, end); + } TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + ep4_free(a); + ep4_free(b); + ep4_free(c); + bn_free(d); + bn_free(n); + return code; +} + +int main(void) { + int r0, r1; + + if (core_init() != RLC_OK) { + core_clean(); + return 1; + } + + util_banner("Tests for the EPX module", 0); + + if (ep_param_set_any_pairf() == RLC_ERR) { + RLC_THROW(ERR_NO_CURVE); + core_clean(); + return 0; + } + + if ((r0 = ep2_curve_is_twist())) { + ep_param_print(); + + util_banner("Utilities:", 1); + + if (memory2() != RLC_OK) { + core_clean(); + return 1; + } + + if (util2() != RLC_OK) { + core_clean(); + return 1; + } + + util_banner("Arithmetic:", 1); + + if (addition2() != RLC_OK) { + core_clean(); + return 1; + } + + if (subtraction2() != RLC_OK) { + core_clean(); + return 1; + } + + if (doubling2() != RLC_OK) { + core_clean(); + return 1; + } + + if (multiplication2() != RLC_OK) { + core_clean(); + return 1; + } + + if (fixed2() != RLC_OK) { + core_clean(); + return 1; + } + + if (simultaneous2() != RLC_OK) { + core_clean(); + return 1; + } + + if (compression2() != RLC_OK) { + core_clean(); + return 1; + } + + if (hashing2() != RLC_OK) { + core_clean(); + return 1; + } + + if (frobenius2() != RLC_OK) { + core_clean(); + return 1; + } + } + + if ((r1 = ep4_curve_is_twist())) { + ep_param_print(); + + util_banner("Utilities:", 1); + + if (memory4() != RLC_OK) { + core_clean(); + return 1; + } + + if (util4() != RLC_OK) { + core_clean(); + return 1; + } + + util_banner("Arithmetic:", 1); + + if (addition4() != RLC_OK) { + core_clean(); + return 1; + } + + if (subtraction4() != RLC_OK) { + core_clean(); + return 1; + } + + if (doubling4() != RLC_OK) { + core_clean(); + return 1; + } + + if (multiplication4() != RLC_OK) { + core_clean(); + return 1; + } + + if (fixed4() != RLC_OK) { + core_clean(); + return 1; + } + + if (simultaneous4() != RLC_OK) { + core_clean(); + return 1; + } + + if (hashing4() != RLC_OK) { + core_clean(); + return 1; + } + + if (frobenius4() != RLC_OK) { + core_clean(); + return 1; + } + } + + if (!r0 && !r1) { + RLC_THROW(ERR_NO_CURVE); + core_clean(); + return 0; } util_banner("All tests have passed.\n", 0); diff --git a/contrib/relic/test/test_err.c b/contrib/relic/test/test_err.c index 16c753643..b87ea2c26 100644 --- a/contrib/relic/test/test_err.c +++ b/contrib/relic/test/test_err.c @@ -70,6 +70,16 @@ static void dummy3(void) { } } +static void dummy4(void) { + RLC_TRY { + dummy3(); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + } +} + + int main(void) { err_t e; char *msg = NULL; @@ -115,6 +125,24 @@ int main(void) { bn_new(a); dummy3(); } + RLC_CATCH(e) { + bn_free(a); + switch (e) { + case ERR_NO_MEMORY: + TEST_END; + break; + } + } + } + + TEST_ONCE("throw in deep try-catch is correct and functions are printed") { + bn_t a; + bn_null(a); + + RLC_TRY { + bn_new(a); + dummy4(); + } RLC_CATCH(e) { bn_free(a); switch (e) { @@ -127,14 +155,14 @@ int main(void) { } #endif - util_banner("All tests have passed.\n", 0); - code = RLC_OK; + end: core_clean(); - if (code == RLC_ERR) + if (code == RLC_ERR) { + util_banner("All tests have passed.\n", 0); return 0; - else { + } else { return 1; } } diff --git a/contrib/relic/test/test_fb.c b/contrib/relic/test/test_fb.c index c3c7728a9..4c153f340 100644 --- a/contrib/relic/test/test_fb.c +++ b/contrib/relic/test/test_fb.c @@ -847,15 +847,13 @@ static int inversion(void) { static int exponentiation(void) { int code = RLC_ERR; - fb_t a, b, c, t[RLC_FB_TABLE_MAX]; + fb_t a, b, c; + fb_st t[RLC_FB_TABLE_MAX]; bn_t d; fb_null(a); fb_null(b); fb_null(c); - for (int i = 0; i < RLC_FB_TABLE_MAX; i++) { - fb_null(t[i]); - } bn_null(d); RLC_TRY { @@ -913,15 +911,11 @@ static int exponentiation(void) { } TEST_END; #endif - for (int i = 0; i < RLC_FB_TABLE; i++) { - fb_new(t[i]); - } - TEST_CASE("iterated squaring is correct") { fb_rand(a); bn_rand(d, RLC_POS, 4); fb_itr_pre(t, d->dp[0]); - fb_itr(b, a, d->dp[0], (const fb_t *)t); + fb_itr(b, a, d->dp[0], (const fb_st *)t); for (int j = 0; j < d->dp[0]; j++) { fb_sqr(a, a); } @@ -932,17 +926,13 @@ static int exponentiation(void) { fb_rand(a); bn_rand(d, RLC_POS, 4); fb_itr_pre(t, -d->dp[0]); - fb_itr(b, a, -d->dp[0], (const fb_t *)t); + fb_itr(b, a, -d->dp[0], (const fb_st *)t); for (int j = 0; j < d->dp[0]; j++) { fb_srt(a, a); } TEST_ASSERT(fb_cmp(a, b) == RLC_EQ, end); } TEST_END; - for (int i = 0; i < RLC_FB_TABLE; i++) { - fb_free(t[i]); - } - #if FB_ITR == BASIC || !defined(STRIP) TEST_CASE("basic iterated squaring is correct") { fb_rand(a); @@ -966,15 +956,11 @@ static int exponentiation(void) { #endif #if FB_ITR == QUICK || !defined(STRIP) - for (int i = 0; i < RLC_FB_TABLE_QUICK; i++) { - fb_new(t[i]); - fb_zero(t[i]); - } TEST_CASE("fast iterated squaring is correct") { fb_rand(a); bn_rand(d, RLC_POS, 4); fb_itr_pre_quick(t, d->dp[0]); - fb_itr_quick(b, a, (const fb_t *)t); + fb_itr_quick(b, a, (const fb_st *)t); for (int j = 0; j < d->dp[0]; j++) { fb_sqr(a, a); } @@ -985,16 +971,12 @@ static int exponentiation(void) { fb_rand(a); bn_rand(d, RLC_POS, 4); fb_itr_pre_quick(t, -d->dp[0]); - fb_itr_quick(b, a, (const fb_t *)t); + fb_itr_quick(b, a, (const fb_st *)t); for (int j = 0; j < d->dp[0]; j++) { fb_srt(a, a); } TEST_ASSERT(fb_cmp(a, b) == RLC_EQ, end); } TEST_END; - - for (int i = 0; i < RLC_FB_TABLE_QUICK; i++) { - fb_free(t[i]); - } #endif } RLC_CATCH_ANY { diff --git a/contrib/relic/test/test_fp.c b/contrib/relic/test/test_fp.c index 291829f8b..05ce289e4 100644 --- a/contrib/relic/test/test_fp.c +++ b/contrib/relic/test/test_fp.c @@ -856,6 +856,17 @@ static int inversion(void) { } TEST_END; #endif +#if FP_INV == JMPDS || !defined(STRIP) + TEST_CASE("jump division step inversion is correct") { + do { + fp_rand(a); + } while (fp_is_zero(a)); + fp_inv(b, a); + fp_inv_jmpds(c, a); + TEST_ASSERT(fp_cmp(c, b) == RLC_EQ, end); + } TEST_END; +#endif + #if FP_INV == LOWER || !defined(STRIP) TEST_CASE("lower inversion is correct") { do { @@ -894,6 +905,66 @@ static int inversion(void) { return code; } +static int symbol(void) { + int code = RLC_ERR; + fp_t a, b; + + fp_null(a); + fp_null(b); + + RLC_TRY { + fp_new(a); + fp_new(b); + + TEST_CASE("symbol computation is correct") { + fp_zero(a); + TEST_ASSERT(fp_smb(a) == 0, end); + fp_rand(a); + fp_sqr(a, a); + TEST_ASSERT(fp_smb(a) == 1, end); + do { + fp_rand(a); + } while(fp_srt(b, a) == 1); + TEST_ASSERT(fp_smb(a) == -1, end); + } + TEST_END; + +#if FP_SMB == BASIC || !defined(STRIP) + TEST_CASE("basic symbol computation is correct") { + fp_rand(a); + TEST_ASSERT(fp_smb(a) == fp_smb_basic(a), end); + } TEST_END; +#endif + +#if FP_SMB == DIVST || !defined(STRIP) + TEST_CASE("division step symbol computation is correct") { + fp_rand(a); + TEST_ASSERT(fp_smb(a) == fp_smb_divst(a), end); + } TEST_END; +#endif +#if FP_SMB == JMPDS || !defined(STRIP) + TEST_CASE("jump division step symbol computation is correct") { + fp_rand(a); + TEST_ASSERT(fp_smb(a) == fp_smb_jmpds(a), end); + } TEST_END; +#endif +#if FP_SMB == LOWER || !defined(STRIP) + TEST_CASE("lower symbol computation is correct") { + fp_rand(a); + TEST_ASSERT(fp_smb(a) == fp_smb_lower(a), end); + } TEST_END; +#endif + } + RLC_CATCH_ANY { + RLC_ERROR(end); + } + code = RLC_OK; + end: + fp_free(a); + fp_free(b); + return code; +} + static int exponentiation(void) { int code = RLC_ERR; fp_t a, b, c; @@ -1147,6 +1218,11 @@ int main(void) { return 1; } + if (symbol() != RLC_OK) { + core_clean(); + return 1; + } + if (exponentiation() != RLC_OK) { core_clean(); return 1; diff --git a/contrib/relic/test/test_fpx.c b/contrib/relic/test/test_fpx.c index 3b043d484..a7c8eaa23 100644 --- a/contrib/relic/test/test_fpx.c +++ b/contrib/relic/test/test_fpx.c @@ -1915,16 +1915,14 @@ static int squaring4(void) { static int inversion4(void) { int code = RLC_ERR; - fp4_t a, b, c; - - fp4_null(a); - fp4_null(b); - fp4_null(c); + fp4_t a, b, c, d[2]; RLC_TRY { fp4_new(a); fp4_new(b); fp4_new(c); + fp4_new(d[0]); + fp4_new(d[1]); TEST_CASE("inversion is correct") { do { @@ -1934,6 +1932,20 @@ static int inversion4(void) { fp4_mul(c, a, b); TEST_ASSERT(fp4_cmp_dig(c, 1) == RLC_EQ, end); } TEST_END; + + TEST_CASE("simultaneous inversion is correct") { + do { + fp4_rand(a); + fp4_rand(b); + } while (fp4_is_zero(a) || fp4_is_zero(b)); + fp4_copy(d[0], a); + fp4_copy(d[1], b); + fp4_inv(a, a); + fp4_inv(b, b); + fp4_inv_sim(d, d, 2); + TEST_ASSERT(fp4_cmp(d[0], a) == RLC_EQ && + fp4_cmp(d[1], b) == RLC_EQ, end); + } TEST_END; } RLC_CATCH_ANY { util_print("FATAL ERROR!\n"); @@ -1944,6 +1956,8 @@ static int inversion4(void) { fp4_free(a); fp4_free(b); fp4_free(c); + fp4_free(d[0]); + fp4_free(d[1]); return code; } @@ -2004,6 +2018,64 @@ static int exponentiation4(void) { return code; } +static int square_root4(void) { + int code = RLC_ERR; + fp4_t a, b, c; + int r; + + fp4_null(a); + fp4_null(b); + fp4_null(c); + + RLC_TRY { + fp4_new(a); + fp4_new(b); + fp4_new(c); + + TEST_CASE("square root extraction is correct") { + fp4_zero(a); + fp4_sqr(c, a); + r = fp4_srt(b, c); + TEST_ASSERT(r, end); + TEST_ASSERT(fp4_cmp(b, a) == RLC_EQ || + fp4_cmp(c, a) == RLC_EQ, end); + fp2_rand(a[0]); + fp2_zero(a[1]); + fp4_sqr(c, a); + r = fp4_srt(b, c); + fp4_neg(c, b); + TEST_ASSERT(r, end); + TEST_ASSERT(fp4_cmp(b, a) == RLC_EQ || + fp4_cmp(c, a) == RLC_EQ, end); + fp2_zero(a[0]); + fp2_rand(a[1]); + fp4_sqr(c, a); + r = fp4_srt(b, c); + fp4_neg(c, b); + TEST_ASSERT(r, end); + TEST_ASSERT(fp4_cmp(b, a) == RLC_EQ || + fp4_cmp(c, a) == RLC_EQ, end); + fp4_rand(a); + fp4_sqr(c, a); + r = fp4_srt(b, c); + fp4_neg(c, b); + TEST_ASSERT(r, end); + TEST_ASSERT(fp4_cmp(b, a) == RLC_EQ || + fp4_cmp(c, a) == RLC_EQ, end); + } TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + fp4_free(a); + fp4_free(b); + fp4_free(c); + return code; +} + static int memory6(void) { err_t e; int code = RLC_ERR; @@ -4286,6 +4358,7 @@ static int cyclotomic12(void) { bn_neg(f, f); fp12_exp_cyc(c, a, f); fp12_inv_cyc(c, c); + TEST_ASSERT(fp12_cmp(b, c) == RLC_EQ, end); /* Try sparse exponents as well. */ bn_set_2b(f, RLC_FP_BITS - 1); bn_set_bit(f, RLC_FP_BITS / 2, 1); @@ -5102,7 +5175,7 @@ static int util24(void) { TEST_CASE("reading and writing a finite field element are consistent") { fp24_rand(a); - fp24_write_bin(bin, sizeof(bin), a); + fp24_write_bin(bin, sizeof(bin), a, 0); fp24_read_bin(b, bin, sizeof(bin)); TEST_ASSERT(fp24_cmp(a, b) == RLC_EQ, end); } @@ -5110,7 +5183,7 @@ static int util24(void) { TEST_CASE("getting the size of a finite field element is correct") { fp24_rand(a); - TEST_ASSERT(fp24_size_bin(a) == 24 * RLC_FP_BYTES, end); + TEST_ASSERT(fp24_size_bin(a, 0) == 24 * RLC_FP_BYTES, end); } TEST_END; } @@ -5397,6 +5470,198 @@ static int squaring24(void) { return code; } +static int cyclotomic24(void) { + int code = RLC_ERR; + fp24_t a, b, c, d[2], e[2]; + bn_t f; + + fp24_null(a); + fp24_null(b); + fp24_null(c); + fp24_null(d[0]); + fp24_null(d[1]) + fp24_null(e[0]); + fp24_null(e[1]); + bn_null(f); + + RLC_TRY { + fp24_new(a); + fp24_new(b); + fp24_new(c); + fp24_new(d[0]); + fp24_new(d[1]); + fp24_new(e[0]); + fp24_new(e[1]); + bn_new(f); + + TEST_CASE("cyclotomic test is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + TEST_ASSERT(fp24_test_cyc(a) == 1, end); + } TEST_END; + + TEST_CASE("compression in cyclotomic subgroup is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_back_cyc(c, a); + TEST_ASSERT(fp24_cmp(a, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("simultaneous decompression in cyclotomic subgroup is correct") { + fp24_rand(d[0]); + fp24_rand(d[1]); + fp24_conv_cyc(d[0], d[0]); + fp24_conv_cyc(d[1], d[1]); + fp24_back_cyc_sim(e, d, 2); + TEST_ASSERT(fp24_cmp(d[0], e[0]) == RLC_EQ && + fp24_cmp(d[1], e[1]) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("cyclotomic squaring is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_sqr(b, a); + fp24_sqr_cyc(c, a); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; + +#if FPX_RDC == BASIC || !defined(STRIP) + TEST_CASE("basic cyclotomic squaring is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_sqr_cyc(b, a); + fp24_sqr_cyc_basic(c, a); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif + +#if FPX_RDC == LAZYR || !defined(STRIP) + TEST_CASE("lazy-reduced cyclotomic squaring is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_sqr_cyc(b, a); + fp24_sqr_cyc_lazyr(c, a); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("compressed squaring is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp4_zero(b[0][0]); + fp4_zero(b[1][1]); + fp4_zero(c[0][0]); + fp4_zero(c[1][1]); + fp24_sqr(b, a); + fp24_sqr_pck(c, a); + fp24_back_cyc(c, c); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; + +#if FPX_RDC == BASIC || !defined(STRIP) + TEST_CASE("basic compressed squaring is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp4_zero(b[0][0]); + fp4_zero(b[1][1]); + fp4_zero(c[0][0]); + fp4_zero(c[1][1]); + fp24_sqr_pck(b, a); + fp24_sqr_pck_basic(c, a); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif + +#if FPX_RDC == LAZYR || !defined(STRIP) + TEST_CASE("lazy-reduced compressed squaring is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp4_zero(b[0][0]); + fp4_zero(b[1][1]); + fp4_zero(c[0][0]); + fp4_zero(c[1][1]); + fp24_sqr_pck(b, a); + fp24_sqr_pck_lazyr(c, a); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("cyclotomic exponentiation is correct") { + fp24_rand(a); + fp24_conv_cyc(a, a); + bn_zero(f); + fp24_exp_cyc(c, a, f); + TEST_ASSERT(fp24_cmp_dig(c, 1) == RLC_EQ, end); + bn_set_dig(f, 1); + fp24_exp_cyc(c, a, f); + TEST_ASSERT(fp24_cmp(c, a) == RLC_EQ, end); + bn_rand(f, RLC_POS, RLC_DIG); + fp24_exp(b, a, f); + fp24_exp_cyc(c, a, f); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + bn_rand(f, RLC_POS, RLC_FP_BITS); + fp24_exp_cyc(b, a, f); + bn_neg(f, f); + fp24_exp_cyc(c, a, f); + fp24_inv_cyc(c, c); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + /* Try sparse exponents as well. */ + bn_set_2b(f, RLC_FP_BITS - 1); + bn_set_bit(f, RLC_FP_BITS / 2, 1); + bn_set_bit(f, 0, 1); + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_exp_cyc(b, a, f); + bn_neg(f, f); + fp24_exp_cyc(c, a, f); + fp24_inv_cyc(c, c); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("sparse cyclotomic exponentiation is correct") { + int g[3] = {0, 0, RLC_FP_BITS - 1}; + do { + bn_rand(f, RLC_POS, RLC_DIG); + g[1] = f->dp[0] % RLC_FP_BITS; + } while (g[1] == 0 || g[1] == RLC_FP_BITS - 1); + bn_set_2b(f, RLC_FP_BITS - 1); + bn_set_bit(f, g[1], 1); + bn_set_bit(f, 0, 1); + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_exp(b, a, f); + fp24_exp_cyc_sps(c, a, g, 3, RLC_POS); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + g[0] = 0; + fp24_exp_cyc_sps(c, a, g, 0, RLC_POS); + TEST_ASSERT(fp24_cmp_dig(c, 1) == RLC_EQ, end); + g[0] = 0; + fp24_exp_cyc_sps(c, a, g, 1, RLC_POS); + TEST_ASSERT(fp24_cmp(c, a) == RLC_EQ, end); + g[0] = -1; + fp24_exp_cyc_sps(b, a, g, 1, RLC_POS); + fp24_inv(b, b); + fp24_sqr_cyc(c, a); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + } TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + fp24_free(a); + fp24_free(b); + fp24_free(c); + fp24_free(d[0]); + fp24_free(d[1]); + fp24_free(e[0]); + fp24_free(e[1]); + bn_free(f); + return code; +} + static int inversion24(void) { int code = RLC_ERR; fp24_t a, b, c; @@ -5461,6 +5726,10 @@ static int exponentiation24(void) { fp24_exp(c, a, d); fp24_inv(c, c); TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); + bn_rand(d, RLC_POS, RLC_DIG); + fp24_exp_dig(b, a, d->dp[0]); + fp24_exp(c, a, d); + TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); } TEST_END; TEST_CASE("frobenius and exponentiation are consistent") { @@ -5488,6 +5757,61 @@ static int exponentiation24(void) { return code; } +static int compression24(void) { + int code = RLC_ERR; + uint8_t bin[24 * RLC_FP_BYTES]; + fp24_t a, b, c; + + fp24_null(a); + fp24_null(b); + fp24_null(c); + + RLC_TRY { + fp24_new(a); + fp24_new(b); + fp24_new(c); + + TEST_CASE("compression is consistent") { + fp24_rand(a); + fp24_pck(b, a); + TEST_ASSERT(fp24_upk(c, b) == 1, end); + TEST_ASSERT(fp24_cmp(a, c) == RLC_EQ, end); + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_pck(b, a); + TEST_ASSERT(fp24_upk(c, b) == 1, end); + TEST_ASSERT(fp24_cmp(a, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("compression is consistent with reading and writing") { + fp24_rand(a); + fp24_conv_cyc(a, a); + fp24_write_bin(bin, 16 * RLC_FP_BYTES, a, 1); + fp24_read_bin(b, bin, 16 * RLC_FP_BYTES); + TEST_ASSERT(fp24_cmp(a, b) == RLC_EQ, end); + } + TEST_END; + + TEST_CASE("getting the size of a compressed field element is correct") { + fp24_rand(a); + TEST_ASSERT(fp24_size_bin(a, 0) == 24 * RLC_FP_BYTES, end); + fp24_conv_cyc(a, a); + TEST_ASSERT(fp24_size_bin(a, 1) == 16 * RLC_FP_BYTES, end); + } + TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + fp24_free(a); + fp24_free(b); + fp24_free(c); + return code; +} + static int memory48(void) { err_t e; int code = RLC_ERR; @@ -6072,6 +6396,7 @@ static int cyclotomic48(void) { bn_neg(f, f); fp48_exp_cyc(c, a, f); fp48_inv_cyc(c, c); + TEST_ASSERT(fp48_cmp(b, c) == RLC_EQ, end); /* Try sparse exponents as well. */ bn_set_2b(f, RLC_FP_BITS - 1); bn_set_bit(f, RLC_FP_BITS / 2, 1); @@ -6818,6 +7143,7 @@ static int cyclotomic54(void) { bn_neg(f, f); fp54_exp_cyc(c, a, f); fp54_inv_cyc(c, c); + TEST_ASSERT(fp54_cmp(b, c) == RLC_EQ, end); /* Try sparse exponents as well. */ bn_set_2b(f, RLC_FP_BITS - 1); bn_set_bit(f, RLC_FP_BITS / 2, 1); @@ -7174,6 +7500,11 @@ int main(void) { core_clean(); return 1; } + + if (square_root4() != RLC_OK) { + core_clean(); + return 1; + } } /* Fp^6 is defined as a cubic extension of Fp^2. */ @@ -7488,6 +7819,16 @@ int main(void) { return 1; } + if (cyclotomic24() != RLC_OK) { + core_clean(); + return 1; + } + + if (compression24() != RLC_OK) { + core_clean(); + return 1; + } + util_banner("Extension of degree 48:", 0); util_banner("Utilities:", 1); diff --git a/contrib/relic/test/test_pc.c b/contrib/relic/test/test_pc.c index 6aada90ba..01b4b13e0 100644 --- a/contrib/relic/test/test_pc.c +++ b/contrib/relic/test/test_pc.c @@ -367,6 +367,18 @@ static int multiplication1(void) { g1_mul(r, p, n); TEST_ASSERT(g1_is_infty(r) == 1, end); } TEST_END; + + TEST_CASE("point multiplication by digit is correct") { + g1_mul_dig(r, p, 0); + TEST_ASSERT(g1_is_infty(r), end); + g1_mul_dig(r, p, 1); + TEST_ASSERT(g1_cmp(p, r) == RLC_EQ, end); + bn_rand(k, RLC_POS, RLC_DIG); + g1_mul(q, p, k); + g1_mul_dig(r, p, k->dp[0]); + TEST_ASSERT(g1_cmp(q, r) == RLC_EQ, end); + } + TEST_END; } RLC_CATCH_ANY { util_print("FATAL ERROR!\n"); @@ -641,7 +653,7 @@ static int memory2(void) { int util2(void) { int l, code = RLC_ERR; g2_t a, b, c; - uint8_t bin[4 * RLC_PC_BYTES + 1]; + uint8_t bin[8 * RLC_PC_BYTES + 1]; g2_null(a); g2_null(b); @@ -945,6 +957,18 @@ static int multiplication2(void) { g2_mul(r, p, n); TEST_ASSERT(g2_is_infty(r) == 1, end); } TEST_END; + + TEST_CASE("point multiplication by digit is correct") { + g2_mul_dig(r, p, 0); + TEST_ASSERT(g2_is_infty(r), end); + g2_mul_dig(r, p, 1); + TEST_ASSERT(g2_cmp(p, r) == RLC_EQ, end); + bn_rand(k, RLC_POS, RLC_DIG); + g2_mul(q, p, k); + g2_mul_dig(r, p, k->dp[0]); + TEST_ASSERT(g2_cmp(q, r) == RLC_EQ, end); + } + TEST_END; } RLC_CATCH_ANY { util_print("FATAL ERROR!\n"); @@ -1157,6 +1181,8 @@ static int validity2(void) { return code; } +#if FP_PRIME != 509 + static int hashing2(void) { int code = RLC_ERR; g2_t a; @@ -1190,6 +1216,8 @@ static int hashing2(void) { return code; } +#endif + static int memory(void) { err_t e; int code = RLC_ERR; @@ -1469,6 +1497,14 @@ int exponentiation(void) { gt_exp(b, b, e); gt_mul(b, a, b); TEST_ASSERT(gt_cmp(b, c) == RLC_EQ, end); + gt_exp_dig(b, a, 0); + TEST_ASSERT(gt_is_unity(b), end); + gt_exp_dig(b, a, 1); + TEST_ASSERT(gt_cmp(a, b) == RLC_EQ, end); + bn_rand(d, RLC_POS, RLC_DIG); + gt_exp(b, a, d); + gt_exp_dig(c, a, d->dp[0]); + TEST_ASSERT(gt_cmp(b, c) == RLC_EQ, end); } TEST_END; } RLC_CATCH_ANY { @@ -1709,9 +1745,11 @@ int test2(void) { return RLC_ERR; } +#if FP_PRIME != 509 if (hashing2() != RLC_OK) { return RLC_ERR; } +#endif return RLC_OK; } diff --git a/contrib/relic/test/test_pp.c b/contrib/relic/test/test_pp.c index 0f8f17c0d..e706a2a91 100644 --- a/contrib/relic/test/test_pp.c +++ b/contrib/relic/test/test_pp.c @@ -1257,7 +1257,6 @@ static int pairing12(void) { TEST_ASSERT(fp12_cmp(e1, e2) == RLC_EQ, end); } TEST_END; -#if 0 TEST_CASE("weil multi-pairing is correct") { ep_rand(p[i % 2]); ep2_rand(q[i % 2]); @@ -1284,7 +1283,6 @@ static int pairing12(void) { TEST_ASSERT(fp12_cmp(e1, e2) == RLC_EQ, end); } TEST_END; #endif -#endif #if PP_MAP == OATEP || !defined(STRIP) TEST_CASE("optimal ate pairing non-degeneracy is correct") { @@ -1366,6 +1364,303 @@ static int pairing12(void) { return code; } +static int doubling24(void) { + int code = RLC_ERR; + bn_t k, n; + ep_t p; + ep4_t q, r, s; + fp24_t e1, e2; + + bn_null(k); + bn_null(n); + ep_null(p); + ep4_null(q); + ep4_null(r); + ep4_null(s); + fp24_null(e1); + fp24_null(e2); + + RLC_TRY { + bn_new(n); + bn_new(k); + ep_new(p); + ep4_new(q); + ep4_new(r); + ep4_new(s); + fp24_new(e1); + fp24_new(e2); + + ep_curve_get_ord(n); + + TEST_CASE("miller doubling is correct") { + ep_rand(p); + ep4_rand(q); + ep4_rand(r); + pp_dbl_k24(e1, r, q, p); + pp_norm_k24(r, r); + ep4_dbl(s, q); + ep4_norm(s, s); + TEST_ASSERT(ep4_cmp(r, s) == RLC_EQ, end); + } TEST_END; + +#if EP_ADD == BASIC || !defined(STRIP) + TEST_CASE("miller doubling in affine coordinates is correct") { + ep_rand(p); + ep4_rand(q); + fp24_zero(e1); + fp24_zero(e2); + fp_neg(p->y, p->y); + pp_dbl_k24_basic(e2, r, q, p); + pp_exp_k24(e2, e2); +#if EP_ADD == PROJC + /* Precompute. */ + fp_dbl(p->z, p->x); + fp_add(p->x, p->z, p->x); +#endif + pp_dbl_k24(e1, r, q, p); + pp_exp_k24(e1, e1); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) + TEST_CASE("miller doubling in projective coordinates is correct") { + ep_rand(p); + ep4_rand(q); + fp24_zero(e1); + fp24_zero(e2); + /* Precompute. */ + fp_neg(p->y, p->y); + fp_dbl(p->z, p->x); + fp_add(p->x, p->z, p->x); + pp_dbl_k24_projc(e2, r, q, p); + pp_exp_k24(e2, e2); +#if EP_ADD == BASIC + /* Revert precomputing. */ + fp_hlv(p->x, p->z); +#endif + pp_dbl_k24(e1, r, q, p); + pp_exp_k24(e1, e1); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + } TEST_END; +#endif + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(n); + bn_free(k); + ep_free(p); + ep4_free(q); + ep4_free(r); + ep4_free(s); + fp24_free(e1); + fp24_free(e2); + return code; +} + +static int addition24(void) { + int code = RLC_ERR; + bn_t k, n; + ep_t p; + ep4_t q, r, s; + fp24_t e1, e2; + + bn_null(k); + bn_null(n); + ep_null(p); + ep4_null(q); + ep4_null(r); + ep4_null(s); + fp24_null(e1); + fp24_null(e2); + + RLC_TRY { + bn_new(n); + bn_new(k); + ep_new(p); + ep4_new(q); + ep4_new(r); + ep4_new(s); + fp24_new(e1); + fp24_new(e2); + + ep_curve_get_ord(n); + + TEST_CASE("miller addition is correct") { + ep_rand(p); + ep4_rand(q); + ep4_rand(r); + ep4_copy(s, r); + pp_add_k24(e1, r, q, p); + pp_norm_k24(r, r); + ep4_add(s, s, q); + ep4_norm(s, s); + TEST_ASSERT(ep4_cmp(r, s) == RLC_EQ, end); + } TEST_END; + +#if EP_ADD == BASIC || !defined(STRIP) + TEST_CASE("miller addition in affine coordinates is correct") { + ep_rand(p); + ep4_rand(q); + ep4_rand(r); + ep4_copy(s, r); + fp24_zero(e1); + fp24_zero(e2); + pp_add_k24(e1, r, q, p); + pp_exp_k24(e1, e1); + pp_add_k24_basic(e2, s, q, p); + pp_exp_k24(e2, e2); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + } TEST_END; +#endif + +#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) + TEST_CASE("miller addition in projective coordinates is correct") { + ep_rand(p); + ep4_rand(q); + ep4_rand(r); + ep4_copy(s, r); + fp24_zero(e1); + fp24_zero(e2); + pp_add_k24(e1, r, q, p); + pp_exp_k24(e1, e1); + pp_add_k24_projc(e2, s, q, p); + pp_exp_k24(e2, e2); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + } TEST_END; +#endif + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(n); + bn_free(k); + ep_free(p); + ep4_free(q); + ep4_free(r); + ep4_free(s); + fp24_free(e1); + fp24_free(e2); + return code; +} + +static int pairing24(void) { + int j, code = RLC_ERR; + bn_t k, n; + ep_t p[2]; + ep4_t q[2], r; + fp24_t e1, e2; + + bn_null(k); + bn_null(n); + fp24_null(e1); + fp24_null(e2); + ep4_null(r); + + RLC_TRY { + bn_new(n); + bn_new(k); + fp24_new(e1); + fp24_new(e2); + ep4_new(r); + + for (j = 0; j < 2; j++) { + ep_null(p[j]); + ep4_null(q[j]); + ep_new(p[j]); + ep4_new(q[j]); + } + + ep_curve_get_ord(n); + + TEST_CASE("pairing non-degeneracy is correct") { + ep_rand(p[0]); + ep4_rand(q[0]); + pp_map_k24(e1, p[0], q[0]); + TEST_ASSERT(fp24_cmp_dig(e1, 1) != RLC_EQ, end); + ep_set_infty(p[0]); + pp_map_k24(e1, p[0], q[0]); + TEST_ASSERT(fp24_cmp_dig(e1, 1) == RLC_EQ, end); + ep_rand(p[0]); + ep4_set_infty(q[0]); + pp_map_k24(e1, p[0], q[0]); + TEST_ASSERT(fp24_cmp_dig(e1, 1) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("pairing is bilinear") { + ep_rand(p[0]); + ep4_rand(q[0]); + bn_rand_mod(k, n); + ep4_mul(r, q[0], k); + pp_map_k24(e1, p[0], r); + pp_map_k24(e2, p[0], q[0]); + fp24_exp(e2, e2, k); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + ep_mul(p[0], p[0], k); + pp_map_k24(e2, p[0], q[0]); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + ep_dbl(p[0], p[0]); + pp_map_k24(e2, p[0], q[0]); + fp24_sqr(e1, e1); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + ep4_dbl(q[0], q[0]); + pp_map_k24(e2, p[0], q[0]); + fp24_sqr(e1, e1); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("multi-pairing is correct") { + ep_rand(p[i % 2]); + ep4_rand(q[i % 2]); + pp_map_k24(e1, p[i % 2], q[i % 2]); + ep_rand(p[1 - (i % 2)]); + ep4_set_infty(q[1 - (i % 2)]); + pp_map_sim_k24(e2, p, q, 2); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + ep_set_infty(p[1 - (i % 2)]); + ep4_rand(q[1 - (i % 2)]); + pp_map_sim_k24(e2, p, q, 2); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + ep4_set_infty(q[i % 2]); + pp_map_sim_k24(e2, p, q, 2); + TEST_ASSERT(fp24_cmp_dig(e2, 1) == RLC_EQ, end); + ep_rand(p[0]); + ep4_rand(q[0]); + pp_map_k24(e1, p[0], q[0]); + ep_rand(p[1]); + ep4_rand(q[1]); + pp_map_k24(e2, p[1], q[1]); + fp24_mul(e1, e1, e2); + pp_map_sim_k24(e2, p, q, 2); + TEST_ASSERT(fp24_cmp(e1, e2) == RLC_EQ, end); + } TEST_END; + } + RLC_CATCH_ANY { + util_print("FATAL ERROR!\n"); + RLC_ERROR(end); + } + code = RLC_OK; + end: + bn_free(n); + bn_free(k); + fp24_free(e1); + fp24_free(e2); + ep4_free(r); + + for (j = 0; j < 2; j++) { + ep_free(p[j]); + ep4_free(q[j]); + } + return code; +} + /* Put test vectors here until we implement E(Fp^8). */ #define QX000 "266A6ACAA4B8DDCFBF97F09DFBEB01999BFBFF872276FA7700114F761E8971C6C25A53CC77E96BCC9579F63D8A39D641B8070B07EF40E93C301A5B49CE87110CC30E044BEE5A2D43" #define QX001 "5009EEB2A67C52B79D0727B408A193FFCE76B4F80C8DCF4D61ECEE5471601CD7A94341F697CE9D375DB5470EA055B73C256CCC0AC12F52EAD276C26E001DDCE02DE634BEFCB9CC7C" @@ -2210,6 +2505,23 @@ int main(void) { } } + if (ep_param_embed() == 24) { + if (doubling24() != RLC_OK) { + core_clean(); + return 1; + } + + if (addition24() != RLC_OK) { + core_clean(); + return 1; + } + + if (pairing24() != RLC_OK) { + core_clean(); + return 1; + } + } + if (ep_param_embed() == 12) { if (doubling12() != RLC_OK) { core_clean(); diff --git a/contrib/relic/test/test_rand.c b/contrib/relic/test/test_rand.c index a1dcf8f2a..e3de369d3 100644 --- a/contrib/relic/test/test_rand.c +++ b/contrib/relic/test/test_rand.c @@ -231,7 +231,7 @@ uint8_t result2[] = { 0x2C, 0xE4, 0xAD, 0x78, 0x2E, 0x7B }; -#elif MD_MAP == BLAKE2S_160 +#elif MD_MAP == B2S160 #define FUNCTION "blake2s-160" @@ -259,7 +259,7 @@ uint8_t result2[] = { 0x98, 0x7B, 0x11, 0x8D, 0x9F, 0x97, 0xA1, 0x4E, 0x67, 0x82 }; -#elif MD_MAP == BLAKE2S_256 +#elif MD_MAP == B2S256 uint8_t seed1[63]; diff --git a/contrib/relic/tools/git-creation-date.sh b/contrib/relic/tools/git-creation-date.sh new file mode 100755 index 000000000..ce70f7036 --- /dev/null +++ b/contrib/relic/tools/git-creation-date.sh @@ -0,0 +1,10 @@ +#!/bin/bash +for file in $(git ls-files *.c *.h *.in *.s *.S *.tmpl) +do + HASH=$(git rev-list HEAD "$file" | tail -n 1) + DATE=$(git show -s --format="%ad" --date=format:'%Y' $HASH --) + printf "%-35s %s\n %s\n" "$file" "$DATE" + sed -i "s/Copyright (c) 20[0-9][0-9]/Copyright (c) $DATE/g" "$file" +done + + diff --git a/js-bindings/wrappers/BignumWrapper.cpp b/js-bindings/wrappers/BignumWrapper.cpp index c99e83a74..5ff4da42f 100644 --- a/js-bindings/wrappers/BignumWrapper.cpp +++ b/js-bindings/wrappers/BignumWrapper.cpp @@ -17,7 +17,7 @@ namespace js_wrappers { Bignum::Bignum() { - bn_init(&content, 1); + bn_make(&content, 1); } Bignum::~Bignum() { diff --git a/js_build.sh b/js_build.sh index 0fb358946..29928af4a 100755 --- a/js_build.sh +++ b/js_build.sh @@ -5,5 +5,5 @@ git submodule update --init --recursive mkdir js_build cd js_build -cmake ../ -DCMAKE_TOOLCHAIN_FILE=$(realpath $(which emcc))/cmake/Modules/Platform/Emscripten.cmake +cmake ../ -DCMAKE_TOOLCHAIN_FILE=$(dirname $(realpath $(which emcc)))/cmake/Modules/Platform/Emscripten.cmake cmake --build . -- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 95bd99aa3..2afe56df0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,7 +7,7 @@ include(FetchContent) if (DEFINED ENV{RELIC_MAIN}) set(RELIC_GIT_TAG "origin/main") else () - set(RELIC_GIT_TAG "1885ae3b681c423c72b65ce1fe70910142cf941c") + set(RELIC_GIT_TAG "bf37129789c7897f4144fe2f15d0bd2ef8091807") endif () message(STATUS "Relic will be built from: ${RELIC_GIT_TAG}") diff --git a/src/elements.cpp b/src/elements.cpp index 39c0ff3a4..2657118cc 100644 --- a/src/elements.cpp +++ b/src/elements.cpp @@ -32,17 +32,11 @@ G1Element G1Element::FromBytes(const Bytes& bytes) buffer[0] = 0x00; buffer[1] &= 0x1f; // erase 3 msbs from given input + bool fZerosOnly = Util::HasOnlyZeros(Bytes(buffer, G1Element::SIZE + 1)); if ((bytes[0] & 0xc0) == 0xc0) { // representing infinity // enforce that infinity must be 0xc0000..00 - if (bytes[0] != 0xc0) { - throw std::invalid_argument( - "Given G1 infinity element must be canonical"); - } - for (int i = 1; i < G1Element::SIZE; ++i) { - if (bytes[i] != 0x00) { - throw std::invalid_argument( - "Given G1 infinity element must be canonical"); - } + if (bytes[0] != 0xc0 || !fZerosOnly) { + throw std::invalid_argument("Given G1 infinity element must be canonical"); } return ele; } else { @@ -51,6 +45,10 @@ G1Element G1Element::FromBytes(const Bytes& bytes) "Given G1 non-infinity element must start with 0b10"); } + if (fZerosOnly) { + throw std::invalid_argument("G1 non-infinity element can't have only zeros"); + } + if (bytes[0] & 0x20) { // sign bit buffer[0] = 0x03; } else { @@ -58,6 +56,7 @@ G1Element G1Element::FromBytes(const Bytes& bytes) } } g1_read_bin(ele.p, buffer, G1Element::SIZE + 1); + BLS::CheckRelicErrors(); ele.CheckValid(); return ele; } @@ -215,24 +214,24 @@ G2Element G2Element::FromBytes(const Bytes& bytes) throw std::invalid_argument( "Given G2 element must always have 48th byte start with 0b000"); } + bool fZerosOnly = Util::HasOnlyZeros(Bytes(buffer, G2Element::SIZE + 1)); if (((bytes[0] & 0xc0) == 0xc0)) { // infinity // enforce that infinity must be 0xc0000..00 - if (bytes[0] != 0xc0) { + if (bytes[0] != 0xc0 || !fZerosOnly) { throw std::invalid_argument( "Given G2 infinity element must be canonical"); } - for (int i = 1; i < G2Element::SIZE; ++i) { - if (bytes[i] != 0x00) { - throw std::invalid_argument( - "Given G2 infinity element must be canonical"); - } - } return ele; } else { if (((bytes[0] & 0xc0) != 0x80)) { throw std::invalid_argument( "G2 non-inf element must have 0th byte start with 0b10"); } + + if (fZerosOnly) { + throw std::invalid_argument("G2 non-infinity element can't have only zeros"); + } + if (bytes[0] & 0x20) { buffer[0] = 0x03; } else { @@ -241,6 +240,7 @@ G2Element G2Element::FromBytes(const Bytes& bytes) } g2_read_bin(ele.q, buffer, G2Element::SIZE + 1); + BLS::CheckRelicErrors(); ele.CheckValid(); return ele; } diff --git a/src/schemes.cpp b/src/schemes.cpp index fe7d37f2e..5948fd24c 100644 --- a/src/schemes.cpp +++ b/src/schemes.cpp @@ -533,7 +533,7 @@ bool AugSchemeMPL::AggregateVerify(const vector& pubkeys, } vector> augMessages(nPubKeys); - for (int i = 0; i < nPubKeys; ++i) { + for (size_t i = 0; i < nPubKeys; ++i) { vector& aug = augMessages[i]; vector&& pubkey = pubkeys[i].Serialize(); aug.reserve(pubkey.size() + messages[i].size()); diff --git a/src/test.cpp b/src/test.cpp index 8c62c5ba9..f2a671fbf 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -29,7 +29,7 @@ using std::vector; using namespace bls; -void TestHKDF(string ikm_hex, string salt_hex, string info_hex, string prk_expected_hex, string okm_expected_hex, int L) { +void TestHKDF(string ikm_hex, string salt_hex, string info_hex, string prk_expected_hex, string okm_expected_hex, size_t L) { vector ikm = Util::HexToBytes(ikm_hex); vector salt = Util::HexToBytes(salt_hex); vector info = Util::HexToBytes(info_hex); @@ -471,9 +471,13 @@ TEST_CASE("Error handling") { vector buf(G1Element::SIZE, 0); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 0xFF; i++) { buf[0] = (uint8_t)i; - REQUIRE_THROWS(G1Element::FromByteVector(buf)); + if (i == 0xc0) { // Infinity prefix shouldn't throw here as we have only zero values + REQUIRE_NOTHROW(G1Element::FromByteVector(buf)); + } else { + REQUIRE_THROWS(G1Element::FromByteVector(buf)); + } } } @@ -481,10 +485,17 @@ TEST_CASE("Error handling") { vector buf(G2Element::SIZE, 0); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 0xFF; i++) { buf[0] = (uint8_t)i; - REQUIRE_THROWS(G2Element::FromByteVector(buf)); + if (i == 0xc0) { // Infinity prefix shouldn't throw here as we have only zero values + REQUIRE_NOTHROW(G2Element::FromByteVector(buf)); + } else { + REQUIRE_THROWS(G2Element::FromByteVector(buf)); + } } + // Trigger "G2 element must always have 48th byte start with 0b000" error case + buf[48] = 0xFF; + REQUIRE_THROWS(G2Element::FromByteVector(buf)); } SECTION("Error handling should be thread safe") @@ -630,7 +641,6 @@ TEST_CASE("Signature tests") SECTION("Should not verify aggregate with same message under BasicScheme") { vector message = {100, 2, 254, 88, 90, 45, 23}; - uint8_t hash[BLS::MESSAGE_HASH_LEN]; vector seed(32, 0x50); vector seed2(32, 0x70); @@ -651,7 +661,6 @@ TEST_CASE("Signature tests") SECTION("Should verify aggregate with same message under AugScheme/PopScheme") { vector message = {100, 2, 254, 88, 90, 45, 23}; - uint8_t hash[BLS::MESSAGE_HASH_LEN]; vector seed(32, 0x50); vector seed2(32, 0x70); @@ -1313,7 +1322,7 @@ TEST_CASE("Threshold Signatures") { // First create the participants and their secrets std::vector participants; - for (int i=0; i < n ; i++) { + for (size_t i=0; i < n ; i++) { Participant participant; participant.id = getRandomSeed(); participant.sk = randPrivKey(); @@ -1322,7 +1331,7 @@ TEST_CASE("Threshold Signatures") { // Create the vectors' coefficients participant.sks.emplace_back(participant.sk); participant.pks.emplace_back(participant.pk); - for (int j = 0; j < (m-1); j++) { + for (size_t j = 0; j < (m-1); j++) { auto sk = randPrivKey(); participant.sks.emplace_back(sk); participant.pks.emplace_back(sk.GetG1Element()); @@ -1332,7 +1341,7 @@ TEST_CASE("Threshold Signatures") { // Second, create shares for every other participant for (Participant& participant : participants) { - for (int j=0; j < n; j++) { + for (size_t j=0; j < n; j++) { RawData id = participants[j].id; participant.sksShares.emplace(id, bls::Threshold::PrivateKeyShare(participant.sks, Bytes(id))); participant.pksShares.emplace(id, bls::Threshold::PublicKeyShare(participant.pks, Bytes(id))); @@ -1342,7 +1351,7 @@ TEST_CASE("Threshold Signatures") { // Third, send shares and verification vectors for (Participant& participant : participants) { - for (int j=0; j < n; j++) { + for (size_t j=0; j < n; j++) { auto& recipient = participants[j]; RawData destId = recipient.id; // S(x) evaluated in participant1.id. @@ -1381,8 +1390,8 @@ TEST_CASE("Threshold Signatures") { // Let's aggregate all the verification vectors to obtain Pa(): std::vector finalVerifVector(participants[0].pks); - for (int j = 1; j < participants.size(); j++) { - for (int i = 0; i < finalVerifVector.size(); i++) { + for (size_t j = 1; j < participants.size(); j++) { + for (size_t i = 0; i < finalVerifVector.size(); i++) { finalVerifVector[i] += participants[j].pks.at(i); } } @@ -1408,7 +1417,7 @@ TEST_CASE("Threshold Signatures") { // Let's aggregate all the SIG(0) values to obtain SIGa(0) // This will be checked for equality against the recovered threshold signature G2Element finalSIG = participants[0].sig; - for (int j = 1; j < participants.size(); j++) { + for (size_t j = 1; j < participants.size(); j++) { finalSIG += participants[j].sig; } diff --git a/src/util.hpp b/src/util.hpp index 16f26b432..43ad6ae6b 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -15,6 +15,7 @@ #ifndef SRC_BLSUTIL_HPP_ #define SRC_BLSUTIL_HPP_ +#include #include #include #include @@ -138,6 +139,10 @@ class Util { return sum; } + static bool HasOnlyZeros(const Bytes& bytes) { + return std::all_of(bytes.begin(), bytes.end(), [](uint8_t byte){ return byte == 0x00; }); + } + private: friend class BLS; static SecureAllocCallback secureAllocCallback;