diff --git a/Makefile b/Makefile index 51a1196..f4d52e1 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,9 @@ include common.mk LIB_DIR=lib OBJ_DIR=obj EXE_DIR=bin -SRC_SRC=fp.cpp bn_c256.cpp bn_c384.cpp +SRC_SRC=fp.cpp bn_c256.cpp bn_c384.cpp she_c256.cpp TEST_SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal_test.cpp fp_tower_test.cpp gmp_test.cpp bn_test.cpp bn384_test.cpp glv_test.cpp paillier_test.cpp she_test.cpp vint_test.cpp bn512_test.cpp -TEST_SRC+=bn_c256_test.cpp bn_c384_test.cpp +TEST_SRC+=bn_c256_test.cpp bn_c384_test.cpp she_c256_test.cpp ifeq ($(CPU),x86-64) MCL_USE_XBYAK?=1 TEST_SRC+=mont_fp_test.cpp sq_test.cpp @@ -29,12 +29,14 @@ MCL_LIB=$(LIB_DIR)/libmcl.a MCL_SNAME=mcl$(SHARE_BASENAME_SUF) BN256_SNAME=mclbn256$(SHARE_BASENAME_SUF) BN384_SNAME=mclbn384$(SHARE_BASENAME_SUF) +SHE256_SNAME=mclshe256$(SHARE_BASENAME_SUF) MCL_SLIB=$(LIB_DIR)/lib$(MCL_SNAME).$(LIB_SUF) BN256_LIB=$(LIB_DIR)/libmclbn256.a BN256_SLIB=$(LIB_DIR)/lib$(BN256_SNAME).$(LIB_SUF) BN384_LIB=$(LIB_DIR)/libmclbn384.a BN384_SLIB=$(LIB_DIR)/lib$(BN384_SNAME).$(LIB_SUF) -all: $(MCL_LIB) $(MCL_SLIB) $(BN256_LIB) $(BN256_SLIB) $(BN384_LIB) $(BN384_SLIB) +SHE256_LIB=$(LIB_DIR)/libmclshe256.a +all: $(MCL_LIB) $(MCL_SLIB) $(BN256_LIB) $(BN256_SLIB) $(BN384_LIB) $(BN384_SLIB) $(SHE256_LIB) #LLVM_VER=-3.8 LLVM_LLC=llc$(LLVM_VER) @@ -57,6 +59,7 @@ ASM_OBJ=$(OBJ_DIR)/$(CPU).o LIB_OBJ=$(OBJ_DIR)/fp.o BN256_OBJ=$(OBJ_DIR)/bn_c256.o BN384_OBJ=$(OBJ_DIR)/bn_c384.o +SHE256_OBJ=$(OBJ_DIR)/she_c256.o FUNC_LIST=src/func.list MCL_USE_LLVM?=1 ifeq ($(MCL_USE_LLVM),1) @@ -101,6 +104,9 @@ $(MCL_SLIB): $(LIB_OBJ) $(BN256_LIB): $(BN256_OBJ) $(AR) $@ $(BN256_OBJ) +$(SHE256_LIB): $(SHE256_OBJ) + $(AR) $@ $(SHE256_OBJ) + ifeq ($(OS),mac) MAC_LDFLAGS+=-l$(MCL_SNAME) -L./lib endif @@ -185,6 +191,9 @@ $(EXE_DIR)/bn_c384_test.exe: $(OBJ_DIR)/bn_c384_test.o $(BN384_LIB) $(MCL_LIB) $(EXE_DIR)/pairing_c.exe: $(OBJ_DIR)/pairing_c.o $(BN256_LIB) $(MCL_LIB) $(PRE)$(CC) $< -o $@ $(BN256_LIB) $(MCL_LIB) $(LDFLAGS) -lstdc++ +$(EXE_DIR)/she_c256_test.exe: $(OBJ_DIR)/she_c256_test.o $(SHE256_LIB) $(MCL_LIB) + $(PRE)$(CXX) $< -o $@ $(SHE256_LIB) $(MCL_LIB) $(LDFLAGS) + SAMPLE_EXE=$(addprefix $(EXE_DIR)/,$(addsuffix .exe,$(basename $(SAMPLE_SRC)))) sample: $(SAMPLE_EXE) $(MCL_LIB) diff --git a/include/mcl/she.h b/include/mcl/she.h new file mode 100644 index 0000000..3d13962 --- /dev/null +++ b/include/mcl/she.h @@ -0,0 +1,139 @@ +#pragma once +/** + @file + @brief C api of somewhat homomorphic encryption with one-time multiplication, based on prime-order pairings + @author MITSUNARI Shigeo(@herumi) + @license modified new BSD license + http://opensource.org/licenses/BSD-3-Clause +*/ +#include + +#ifdef _MSC_VER +#ifdef MCLSHE_DLL_EXPORT +#define MCLSHE_DLL_API __declspec(dllexport) +#else +#define MCLSHE_DLL_API __declspec(dllimport) +#ifndef MCLSHE_NO_AUTOLINK + #if MCLBN_FP_UNIT_SIZE == 4 + #pragma comment(lib, "mclshe256.lib") + #elif MCLBN_FP_UNIT_SIZE == 6 + #pragma comment(lib, "mclshe384.lib") + #else + #pragma comment(lib, "mclshe512.lib") + #endif +#endif +#endif +#else +#define MCLSHE_DLL_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + mclBnFr x; + mclBnFr y; +} sheSecretKey; + +typedef struct { + mclBnG1 xP; + mclBnG2 yQ; +} shePublicKey; + +typedef struct { + mclBnG1 S; + mclBnG1 T; +} sheCipherTextG1; + +typedef struct { + mclBnG2 S; + mclBnG2 T; +} sheCipherTextG2; + +typedef struct { + mclBnGT g[4]; +} sheCipherTextGT; + +/* + initialize this library + call this once before using the other functions + @param curve [in] enum value defined in mcl/bn.h + @param maxUnitSize [in] MCLBN_FP_UNIT_SIZE (fixed) + return 0 if success + @note sheInit() is thread safe and serialized if it is called simultaneously + but don't call it while using other functions. +*/ +MCLSHE_DLL_API int sheInit(int curve, int maxUnitSize); + +// return written byte size if success else 0 +MCLSHE_DLL_API size_t sheSecretKeySerialize(void *buf, size_t maxBufSize, const sheSecretKey *sec); +MCLSHE_DLL_API size_t shePublicKeySerialize(void *buf, size_t maxBufSize, const shePublicKey *pub); +MCLSHE_DLL_API size_t sheCipherTextG1Serialize(void *buf, size_t maxBufSize, const sheCipherTextG1 *c); +MCLSHE_DLL_API size_t sheCipherTextG2Serialize(void *buf, size_t maxBufSize, const sheCipherTextG2 *c); +MCLSHE_DLL_API size_t sheCipherTextGTSerialize(void *buf, size_t maxBufSize, const sheCipherTextGT *c); + +// return 0 if success else -1 +MCLSHE_DLL_API int sheSecretKeyDeserialize(sheSecretKey* sec, const void *buf, size_t bufSize); +MCLSHE_DLL_API int shePublicKeyDeserialize(shePublicKey* pub, const void *buf, size_t bufSize); +MCLSHE_DLL_API int sheCipherTextG1Deserialize(sheCipherTextG1* c, const void *buf, size_t bufSize); +MCLSHE_DLL_API int sheCipherTextG2Deserialize(sheCipherTextG2* c, const void *buf, size_t bufSize); +MCLSHE_DLL_API int sheCipherTextGTDeserialize(sheCipherTextGT* c, const void *buf, size_t bufSize); + +/* + set secretKey if system has /dev/urandom or CryptGenRandom + return 0 if success else -1 +*/ +MCLSHE_DLL_API int sheSecretKeySetByCSPRNG(sheSecretKey *sec); + +MCLSHE_DLL_API void sheGetPublicKey(shePublicKey *pub, const sheSecretKey *sec); + +/* + make table to decode DLP + return 0 if success else -1 +*/ +MCLSHE_DLL_API int sheSetRangeForDLP(size_t hashSize, size_t tryNum); + +// return 0 if success else -1 +MCLSHE_DLL_API int sheEncG1(sheCipherTextG1 *c, const shePublicKey *pub, int64_t m); +MCLSHE_DLL_API int sheEncG2(sheCipherTextG2 *c, const shePublicKey *pub, int64_t m); +MCLSHE_DLL_API int sheEncGT(sheCipherTextGT *c, const shePublicKey *pub, int64_t m); + +#define MCLSHE_ERR_DECODE 0x7fffffffffffffffll + +// return MCLSHE_ERR_DECODE if error +MCLSHE_DLL_API int64_t sheDecG1(const sheSecretKey *sec, const sheCipherTextG1 *c); +//MCLSHE_DLL_API int64_t sheDecG2(const sheSecretKey *sec, const sheCipherTextG2 *c); +MCLSHE_DLL_API int64_t sheDecGT(const sheSecretKey *sec, const sheCipherTextGT *c); + +// return 0 if success +// z = x + y +MCLSHE_DLL_API int sheAddG1(sheCipherTextG1 *z, const sheCipherTextG1 *x, const sheCipherTextG1 *y); +MCLSHE_DLL_API int sheAddG2(sheCipherTextG2 *z, const sheCipherTextG2 *x, const sheCipherTextG2 *y); +MCLSHE_DLL_API int sheAddGT(sheCipherTextGT *z, const sheCipherTextGT *x, const sheCipherTextGT *y); + +// return 0 if success +// z = x - y +MCLSHE_DLL_API int sheSubG1(sheCipherTextG1 *z, const sheCipherTextG1 *x, const sheCipherTextG1 *y); +MCLSHE_DLL_API int sheSubG2(sheCipherTextG2 *z, const sheCipherTextG2 *x, const sheCipherTextG2 *y); +MCLSHE_DLL_API int sheSubGT(sheCipherTextGT *z, const sheCipherTextGT *x, const sheCipherTextGT *y); + +// return 0 if success +// z = x * y +MCLSHE_DLL_API int sheMulG1(sheCipherTextG1 *z, const sheCipherTextG1 *x, int64_t y); +MCLSHE_DLL_API int sheMulG2(sheCipherTextG2 *z, const sheCipherTextG2 *x, int64_t y); +MCLSHE_DLL_API int sheMulGT(sheCipherTextGT *z, const sheCipherTextGT *x, int64_t y); + +// return 0 if success +// z = x * y +MCLSHE_DLL_API int sheMul(sheCipherTextGT *z, const sheCipherTextG1 *x, const sheCipherTextG2 *y); + +// return 0 if success +// rerandomize(c) +MCLSHE_DLL_API int sheReRandG1(sheCipherTextG1 *c, const shePublicKey *pub); +MCLSHE_DLL_API int sheReRandG2(sheCipherTextG2 *c, const shePublicKey *pub); +MCLSHE_DLL_API int sheReRandGT(sheCipherTextGT *c, const shePublicKey *pub); + +#ifdef __cplusplus +} +#endif diff --git a/mklib.bat b/mklib.bat index ece2333..ac1b17d 100644 --- a/mklib.bat +++ b/mklib.bat @@ -17,3 +17,8 @@ echo cl /c %CFLAGS% src\bn_c384.cpp /Foobj\bn_c384.obj cl /c %CFLAGS% src\bn_c384.cpp /Foobj\bn_c384.obj echo link /nologo /DLL /OUT:bin\mclbn384.dll obj\bn_c384.obj obj\fp.obj %LDFLAGS% /implib:lib\mclbn384.lib link /nologo /DLL /OUT:bin\mclbn384.dll obj\bn_c384.obj obj\fp.obj %LDFLAGS% /implib:lib\mclbn384.lib + +echo cl /c %CFLAGS% src\she_c256.cpp /Foobj\she_c256.obj + cl /c %CFLAGS% src\she_c256.cpp /Foobj\she_c256.obj +echo link /nologo /DLL /OUT:bin\mclbn256.dll obj\she_c256.obj obj\fp.obj %LDFLAGS% /implib:lib\mclshe256.lib + link /nologo /DLL /OUT:bin\mclbn256.dll obj\she_c256.obj obj\fp.obj %LDFLAGS% /implib:lib\mclshe256.lib diff --git a/src/she_c256.cpp b/src/she_c256.cpp new file mode 100644 index 0000000..84873e4 --- /dev/null +++ b/src/she_c256.cpp @@ -0,0 +1,2 @@ +#define MCLBN_FP_UNIT_SIZE 4 +#include "she_c_impl.hpp" diff --git a/src/she_c_impl.hpp b/src/she_c_impl.hpp new file mode 100644 index 0000000..85d2e86 --- /dev/null +++ b/src/she_c_impl.hpp @@ -0,0 +1,364 @@ +#include +#include +#include +#include +#include +#include +#include +#include "../mcl/src/bn_c_impl.hpp" +#define MCLSHE_DLL_EXPORT + +#include +#include + +using namespace mcl::she; +using namespace mcl::bn_current; + +#if defined(CYBOZU_CPP_VERSION) && CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 +#include + #define USE_STD_MUTEX +#else +#include +#endif + +static SecretKey *cast(sheSecretKey *p) { return reinterpret_cast(p); } +static const SecretKey *cast(const sheSecretKey *p) { return reinterpret_cast(p); } + +static PublicKey *cast(shePublicKey *p) { return reinterpret_cast(p); } +static const PublicKey *cast(const shePublicKey *p) { return reinterpret_cast(p); } + +static CipherTextG1 *cast(sheCipherTextG1 *p) { return reinterpret_cast(p); } +static const CipherTextG1 *cast(const sheCipherTextG1 *p) { return reinterpret_cast(p); } + +static CipherTextG2 *cast(sheCipherTextG2 *p) { return reinterpret_cast(p); } +static const CipherTextG2 *cast(const sheCipherTextG2 *p) { return reinterpret_cast(p); } + +static CipherTextGT *cast(sheCipherTextGT *p) { return reinterpret_cast(p); } +static const CipherTextGT *cast(const sheCipherTextGT *p) { return reinterpret_cast(p); } + +int sheInit(int curve, int maxUnitSize) + try +{ + if (maxUnitSize != MCLBN_FP_UNIT_SIZE) { + printf("err sheInit:maxUnitSize is mismatch %d %d\n", maxUnitSize, MCLBN_FP_UNIT_SIZE); + return -1; + } +#ifdef USE_STD_MUTEX + static std::mutex m; + std::lock_guard lock(m); +#else + static cybozu::Mutex m; + cybozu::AutoLock lock(m); +#endif + static int g_curve = -1; + if (g_curve == curve) return 0; + + mcl::bn::CurveParam cp; + switch (curve) { + case mclBn_CurveFp254BNb: + cp = mcl::bn::CurveFp254BNb; + break; + case mclBn_CurveFp382_1: + cp = mcl::bn::CurveFp382_1; + break; + case mclBn_CurveFp382_2: + cp = mcl::bn::CurveFp382_2; + break; + case mclBn_CurveFp462: + cp = mcl::bn::CurveFp462; + break; + default: + printf("err bad curve %d\n", curve); + return -1; + } + SHE::init(cp); + g_curve = curve; + return 0; +} catch (std::exception& e) { + printf("err sheInit %s\n", e.what()); + return -1; +} + +size_t sheSecretKeySerialize(void *buf, size_t maxBufSize, const sheSecretKey *sec) +{ + char *p = (char *)buf; + size_t n = mclBnFr_serialize(p, maxBufSize, &sec->x); + if (n == 0) return 0; + return n += mclBnFr_serialize(p + n, maxBufSize - n, &sec->y); +} + +size_t shePublicKeySerialize(void *buf, size_t maxBufSize, const shePublicKey *pub) +{ + char *p = (char *)buf; + size_t n = mclBnG1_serialize(p, maxBufSize, &pub->xP); + if (n == 0) return 0; + return n += mclBnG2_serialize(p + n, maxBufSize - n, &pub->yQ); +} + +size_t sheCipherTextG1Serialize(void *buf, size_t maxBufSize, const sheCipherTextG1 *c) +{ + char *p = (char *)buf; + size_t n = mclBnG1_serialize(p, maxBufSize, &c->S); + if (n == 0) return 0; + return n += mclBnG1_serialize(p + n, maxBufSize - n, &c->T); +} + +size_t sheCipherTextG2Serialize(void *buf, size_t maxBufSize, const sheCipherTextG2 *c) +{ + char *p = (char *)buf; + size_t n = mclBnG2_serialize(p, maxBufSize, &c->S); + if (n == 0) return 0; + return n += mclBnG2_serialize(p + n, maxBufSize - n, &c->T); +} + +size_t sheCipherTextGTSerialize(void *buf, size_t maxBufSize, const sheCipherTextGT *c) +{ + char *p = (char *)buf; + size_t n = 0; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(c->g); i++) { + size_t r = mclBnGT_serialize(p + n, maxBufSize - n, &c->g[i]); + if (r == 0) return 0; + n += r; + } + return n; +} + +int sheSecretKeyDeserialize(sheSecretKey* sec, const void *buf, size_t bufSize) +{ + const char *p = (const char *)buf; + if (mclBnFr_deserialize(&sec->x, p, bufSize)) return -1; + const size_t size = Fr::getByteSize(); + return mclBnFr_deserialize(&sec->y, p + size, bufSize - size); +} + +int shePublicKeyDeserialize(shePublicKey* sec, const void *buf, size_t bufSize) +{ + const char *p = (const char *)buf; + if (mclBnG1_deserialize(&sec->xP, p, bufSize)) return -1; + const size_t size = Fr::getByteSize(); + return mclBnG2_deserialize(&sec->yQ, p + size, bufSize - size); +} + +int sheCipherTextG1Deserialize(sheCipherTextG1* c, const void *buf, size_t bufSize) +{ + const char *p = (const char *)buf; + if (mclBnG1_deserialize(&c->S, p, bufSize)) return -1; + const size_t size = Fr::getByteSize(); + return mclBnG1_deserialize(&c->T, p + size, bufSize - size); +} + +int sheCipherTextG2Deserialize(sheCipherTextG2* c, const void *buf, size_t bufSize) +{ + const char *p = (const char *)buf; + if (mclBnG2_deserialize(&c->S, p, bufSize)) return -1; + const size_t size = Fr::getByteSize() * 2; + return mclBnG2_deserialize(&c->T, p + size, bufSize - size); +} + +int sheCipherTextGTDeserialize(sheCipherTextGT* c, const void *buf, size_t bufSize) +{ + const char *p = (const char *)buf; + const size_t size = Fr::getByteSize() * 12; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(c->g); i++) { + if (mclBnGT_deserialize(&c->g[i], p + size * i, bufSize - size * i)) return -1; + } + return 0; +} + +int sheSecretKeySetByCSPRNG(sheSecretKey *sec) + try +{ + cast(sec)->setByCSPRNG(); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +void sheGetPublicKey(shePublicKey *pub, const sheSecretKey *sec) +{ + cast(sec)->getPublicKey(*cast(pub)); +} + +int sheSetRangeForDLP(size_t hashSize, size_t tryNum) + try +{ + SHE::setRangeForDLP(hashSize, tryNum); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheEncG1(sheCipherTextG1 *c, const shePublicKey *pub, int64_t m) + try +{ + cast(pub)->enc(*cast(c), m); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheEncG2(sheCipherTextG2 *c, const shePublicKey *pub, int64_t m) + try +{ + cast(pub)->enc(*cast(c), m); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheEncGT(sheCipherTextGT *c, const shePublicKey *pub, int64_t m) + try +{ + cast(pub)->enc(*cast(c), m); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int64_t sheDecG1(const sheSecretKey *sec, const sheCipherTextG1 *c) + try +{ + return cast(sec)->dec(*cast(c)); +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return MCLSHE_ERR_DECODE; +} + +int64_t sheDecGT(const sheSecretKey *sec, const sheCipherTextGT *c) + try +{ + return cast(sec)->dec(*cast(c)); +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return MCLSHE_ERR_DECODE; +} + +int sheAddG1(sheCipherTextG1 *z, const sheCipherTextG1 *x, const sheCipherTextG1 *y) + try +{ + CipherTextG1::add(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheAddG2(sheCipherTextG2 *z, const sheCipherTextG2 *x, const sheCipherTextG2 *y) + try +{ + CipherTextG2::add(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} +int sheAddGT(sheCipherTextGT *z, const sheCipherTextGT *x, const sheCipherTextGT *y) + try +{ + CipherTextGT::add(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheSubG1(sheCipherTextG1 *z, const sheCipherTextG1 *x, const sheCipherTextG1 *y) + try +{ + CipherTextG1::sub(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheSubG2(sheCipherTextG2 *z, const sheCipherTextG2 *x, const sheCipherTextG2 *y) + try +{ + CipherTextG2::sub(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} +int sheSubGT(sheCipherTextGT *z, const sheCipherTextGT *x, const sheCipherTextGT *y) + try +{ + CipherTextGT::sub(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheMulG1(sheCipherTextG1 *z, const sheCipherTextG1 *x, int64_t y) + try +{ + CipherTextG1::mul(*cast(z), *cast(x), y); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheMulG2(sheCipherTextG2 *z, const sheCipherTextG2 *x, int64_t y) + try +{ + CipherTextG2::mul(*cast(z), *cast(x), y); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} +int sheMulGT(sheCipherTextGT *z, const sheCipherTextGT *x, int64_t y) + try +{ + CipherTextGT::mul(*cast(z), *cast(x), y); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheMul(sheCipherTextGT *z, const sheCipherTextG1 *x, const sheCipherTextG2 *y) + try +{ + CipherTextGT::mul(*cast(z), *cast(x), *cast(y)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} + +int sheReRandG1(sheCipherTextG1 *c, const shePublicKey *pub) + try +{ + cast(pub)->reRand(*cast(c)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} +int sheReRandG2(sheCipherTextG2 *c, const shePublicKey *pub) + try +{ + cast(pub)->reRand(*cast(c)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} +int sheReRandGT(sheCipherTextGT *c, const shePublicKey *pub) + try +{ + cast(pub)->reRand(*cast(c)); + return 0; +} catch (std::exception& e) { + printf("err %s\n", e.what()); + return -1; +} diff --git a/test/she_c256_test.cpp b/test/she_c256_test.cpp new file mode 100644 index 0000000..3e458b6 --- /dev/null +++ b/test/she_c256_test.cpp @@ -0,0 +1,2 @@ +#define MCLBN_FP_UNIT_SIZE 4 +#include "she_c_test.hpp" diff --git a/test/she_c_test.hpp b/test/she_c_test.hpp new file mode 100644 index 0000000..1dd2165 --- /dev/null +++ b/test/she_c_test.hpp @@ -0,0 +1,184 @@ +#include +#include + +const size_t hashSize = 1 << 10; +const size_t tryNum = 1024; + +CYBOZU_TEST_AUTO(init) +{ + int curve; +#if MCLBN_FP_UNIT_SIZE == 4 + curve = mclBn_CurveFp254BNb; +#elif MCLBN_FP_UNIT_SIZE == 6 + curve = mclBn_CurveFp382_1; +#elif MCLBN_FP_UNIT_SIZE == 8 + curve = mclBn_CurveFp462; +#endif + int ret; + ret = sheInit(curve, MCLBN_FP_UNIT_SIZE); + CYBOZU_TEST_ASSERT(ret == 0); + ret = sheSetRangeForDLP(hashSize, tryNum); + CYBOZU_TEST_ASSERT(ret == 0); +} + +CYBOZU_TEST_AUTO(encDec) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m = 123; + sheCipherTextG1 c1; + sheCipherTextGT ct; + sheEncG1(&c1, &pub, m); + sheEncGT(&ct, &pub, m); + + CYBOZU_TEST_EQUAL(sheDecG1(&sec, &c1), m); + CYBOZU_TEST_EQUAL(sheDecGT(&sec, &ct), m); +} + +CYBOZU_TEST_AUTO(addMul) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m1 = 12; + int64_t m2 = -9; + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheCipherTextGT ct; + sheEncG1(&c1, &pub, m1); + sheEncG2(&c2, &pub, m2); + sheMul(&ct, &c1, &c2); + + CYBOZU_TEST_EQUAL(sheDecGT(&sec, &ct), m1 * m2); +} + +CYBOZU_TEST_AUTO(allOp) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m1 = 12; + int64_t m2 = -9; + int64_t m3 = 12; + int64_t m4 = -9; + sheCipherTextG1 c11, c12; + sheCipherTextG2 c21, c22; + sheCipherTextGT ct; + sheEncG1(&c11, &pub, m1); + sheEncG1(&c12, &pub, m2); + sheSubG1(&c11, &c11, &c12); // m1 - m2 + sheMulG1(&c11, &c11, 4); // 4 * (m1 - m2) + + sheEncG2(&c21, &pub, m3); + sheEncG2(&c22, &pub, m4); + sheSubG2(&c21, &c21, &c22); // m3 - m4 + sheMulG2(&c21, &c21, -5); // -5 * (m3 - m4) + sheMul(&ct, &c11, &c21); // -20 * (m1 - m2) * (m3 - m4) + sheAddGT(&ct, &ct, &ct); // -40 * (m1 - m2) * (m3 - m4) + sheMulGT(&ct, &ct, -4); // 160 * (m1 - m2) * (m3 - m4) + + int64_t t = 160 * (m1 - m2) * (m3 - m4); + CYBOZU_TEST_EQUAL(sheDecGT(&sec, &ct), t); +} + +CYBOZU_TEST_AUTO(rerand) +{ + sheSecretKey sec; + sheSecretKeySetByCSPRNG(&sec); + shePublicKey pub; + sheGetPublicKey(&pub, &sec); + + int64_t m1 = 12; + int64_t m2 = -9; + int64_t m3 = 12; + sheCipherTextG1 c1; + sheCipherTextG2 c2; + sheCipherTextGT ct1, ct2; + sheEncG1(&c1, &pub, m1); + sheReRandG1(&c1, &pub); + + sheEncG2(&c2, &pub, m2); + sheReRandG2(&c2, &pub); + + sheEncGT(&ct1, &pub, m3); + sheReRandGT(&ct1, &pub); + + sheMul(&ct2, &c1, &c2); + sheReRandGT(&ct2, &pub); + sheAddGT(&ct1, &ct1, &ct2); + + CYBOZU_TEST_EQUAL(sheDecGT(&sec, &ct1), m1 * m2 + m3); +} + +CYBOZU_TEST_AUTO(serialize) +{ + sheSecretKey sec1, sec2; + sheSecretKeySetByCSPRNG(&sec1); + shePublicKey pub1, pub2; + sheGetPublicKey(&pub1, &sec1); + + char buf1[2048], buf2[2048]; + size_t n1, n2; + size_t r, size; + const size_t sizeofFr = mclBn_getOpUnitSize() * 8; + + size = sizeofFr * 2; + n1 = sheSecretKeySerialize(buf1, sizeof(buf1), &sec1); + CYBOZU_TEST_EQUAL(n1, size); + r = sheSecretKeyDeserialize(&sec2, buf1, n1); + CYBOZU_TEST_ASSERT(r == 0); + n2 = sheSecretKeySerialize(buf2, sizeof(buf2), &sec2); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + size = sizeofFr * 3; + n1 = shePublicKeySerialize(buf1, sizeof(buf1), &pub1); + CYBOZU_TEST_EQUAL(n1, size); + r = shePublicKeyDeserialize(&pub2, buf1, n1); + CYBOZU_TEST_ASSERT(r == 0); + n2 = shePublicKeySerialize(buf2, sizeof(buf2), &pub2); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + int m = 123; + sheCipherTextG1 c11, c12; + sheCipherTextG2 c21, c22; + sheCipherTextGT ct1, ct2; + sheEncG1(&c11, &pub2, m); + sheEncG2(&c21, &pub2, m); + sheEncGT(&ct1, &pub2, m); + + size = sizeofFr * 2; + n1 = sheCipherTextG1Serialize(buf1, sizeof(buf1), &c11); + CYBOZU_TEST_EQUAL(n1, size); + r = sheCipherTextG1Deserialize(&c12, buf1, n1); + CYBOZU_TEST_ASSERT(r == 0); + n2 = sheCipherTextG1Serialize(buf2, sizeof(buf2), &c12); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + size = sizeofFr * 4; + n1 = sheCipherTextG2Serialize(buf1, sizeof(buf1), &c21); + CYBOZU_TEST_EQUAL(n1, size); + r = sheCipherTextG2Deserialize(&c22, buf1, n1); + CYBOZU_TEST_ASSERT(r == 0); + n2 = sheCipherTextG2Serialize(buf2, sizeof(buf2), &c22); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); + + size = sizeofFr * 12 * 4; + n1 = sheCipherTextGTSerialize(buf1, sizeof(buf1), &ct1); + CYBOZU_TEST_EQUAL(n1, size); + r = sheCipherTextGTDeserialize(&ct2, buf1, n1); + CYBOZU_TEST_ASSERT(r == 0); + n2 = sheCipherTextGTSerialize(buf2, sizeof(buf2), &ct2); + CYBOZU_TEST_EQUAL(n2, size); + CYBOZU_TEST_EQUAL_ARRAY(buf1, buf2, n2); +}