From cfd56e2576f55a5e22804e3612b4004c0d6d9ef3 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Sat, 15 Sep 2018 22:03:40 +0900 Subject: remove duplicated C++ code and libbls.a --- Makefile | 40 ++--- include/bls/bls.hpp | 369 +++++++++++++++++++++++++++++++--------- mklib.bat | 2 - readme.md | 9 +- setvar.bat | 2 +- src/bls.cpp | 479 ---------------------------------------------------- src/bls_c.cpp | 414 --------------------------------------------- src/bls_c384.cpp | 3 + src/bls_c_impl.hpp | 414 +++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 724 insertions(+), 1008 deletions(-) delete mode 100644 src/bls.cpp delete mode 100644 src/bls_c.cpp create mode 100644 src/bls_c384.cpp create mode 100644 src/bls_c_impl.hpp diff --git a/Makefile b/Makefile index af34e52..83e8d83 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ EXE_DIR=bin CFLAGS += -std=c++11 LDFLAGS += -lpthread -SRC_SRC=bls.cpp bls_c.cpp +SRC_SRC=bls_c384.cpp TEST_SRC=bls_test.cpp bls_c384_test.cpp SAMPLE_SRC=bls_smpl.cpp @@ -27,29 +27,19 @@ ifeq ($(DISABLE_THREAD_TEST),1) endif SHARE_BASENAME_SUF?=_dy -################################################################## -BLS_LIB=$(LIB_DIR)/libbls.a -LIB_OBJ=$(OBJ_DIR)/bls.o - -$(BLS_LIB): $(LIB_OBJ) - $(AR) $@ $(LIB_OBJ) +BLS384_LIB=$(LIB_DIR)/libbls384.a +BLS384_SNAME=bls384$(SHARE_BASENAME_SUF) +BLS384_SLIB=$(LIB_DIR)/lib$(BLS384_SNAME).$(LIB_SUF) +all: $(BLS384_LIB) $(BLS384_SLIB) MCL_LIB=../mcl/lib/libmcl.a -BN384_LIB=../mcl/lib/libmclbn384.a $(MCL_LIB): $(MAKE) -C ../mcl -################################################################## - -BLS384_LIB=$(LIB_DIR)/libbls384.a -BLS384_SNAME=bls384$(SHARE_BASENAME_SUF) -BLS384_SLIB=$(LIB_DIR)/lib$(BLS384_SNAME).$(LIB_SUF) -all: $(BLS_LIB) $(BLS384_SLIB) - -$(BLS384_LIB): $(LIB_OBJ) $(OBJ_DIR)/bls_c384.o - $(AR) $@ $(LIB_OBJ) $(OBJ_DIR)/bls_c384.o +$(BLS384_LIB): $(OBJ_DIR)/bls_c384.o + $(AR) $@ $(OBJ_DIR)/bls_c384.o ifneq ($(findstring $(OS),mac/mingw64),) BLS384_SLIB_LDFLAGS+=-lgmpxx -lgmp -lcrypto -lstdc++ @@ -67,14 +57,14 @@ VPATH=test sample src $(OBJ_DIR)/%.o: %.cpp $(PRE)$(CXX) $(CFLAGS) -c $< -o $@ -MMD -MP -MF $(@:.o=.d) -$(OBJ_DIR)/bls_c384.o: bls_c.cpp - $(PRE)$(CXX) $(CFLAGS) -c $< -o $@ -MMD -MP -MF $(@:.o=.d) -DMBN_FP_UNIT_SIZE=6 +$(OBJ_DIR)/bls_c384.o: bls_c384.cpp + $(PRE)$(CXX) $(CFLAGS) -c $< -o $@ -MMD -MP -MF $(@:.o=.d) -DMCL_FP_UNIT_SIZE=6 -$(EXE_DIR)/%.exe: $(OBJ_DIR)/%.o $(BLS_LIB) $(BLS384_LIB) $(MCL_LIB) - $(PRE)$(CXX) $< -o $@ $(BLS_LIB) $(BLS384_LIB) -lmcl -L../mcl/lib $(LDFLAGS) +$(EXE_DIR)/%.exe: $(OBJ_DIR)/%.o $(BLS384_LIB) $(MCL_LIB) + $(PRE)$(CXX) $< -o $@ $(BLS384_LIB) -lmcl -L../mcl/lib $(LDFLAGS) SAMPLE_EXE=$(addprefix $(EXE_DIR)/,$(SAMPLE_SRC:.cpp=.exe)) -sample: $(SAMPLE_EXE) $(BLS_LIB) +sample: $(SAMPLE_EXE) TEST_EXE=$(addprefix $(EXE_DIR)/,$(TEST_SRC:.cpp=.exe)) test: $(TEST_EXE) @@ -99,16 +89,16 @@ EMCC_OPT+=-s WASM=1 -s NO_EXIT_RUNTIME=1 -s MODULARIZE=1 #-s ASSERTIONS=1 EMCC_OPT+=-DCYBOZU_MINIMUM_EXCEPTION EMCC_OPT+=-s ABORTING_MALLOC=0 EMCC_OPT+=-DMCLBN_FP_UNIT_SIZE=6 -JS_DEP=src/bls_c.cpp ../mcl/src/fp.cpp Makefile +JS_DEP=src/bls_c384.cpp ../mcl/src/fp.cpp Makefile ../bls-wasm/bls_c.js: $(JS_DEP) - emcc -o $@ src/bls_c.cpp ../mcl/src/fp.cpp $(EMCC_OPT) -DMCL_MAX_BIT_SIZE=384 -DMCL_USE_WEB_CRYPTO_API -s DISABLE_EXCEPTION_CATCHING=1 -DCYBOZU_DONT_USE_EXCEPTION -DCYBOZU_DONT_USE_STRING -DMCL_DONT_USE_CSPRNG -fno-exceptions -MD -MP -MF obj/bls_c.d + emcc -o $@ src/bls_c384.cpp ../mcl/src/fp.cpp $(EMCC_OPT) -DMCL_MAX_BIT_SIZE=384 -DMCL_USE_WEB_CRYPTO_API -s DISABLE_EXCEPTION_CATCHING=1 -DCYBOZU_DONT_USE_EXCEPTION -DCYBOZU_DONT_USE_STRING -DMCL_DONT_USE_CSPRNG -fno-exceptions -MD -MP -MF obj/bls_c384.d bls-wasm: $(MAKE) ../bls-wasm/bls_c.js clean: - $(RM) $(BLS_LIB) $(OBJ_DIR)/*.d $(OBJ_DIR)/*.o $(EXE_DIR)/*.exe $(GEN_EXE) $(ASM_SRC) $(ASM_OBJ) $(LIB_OBJ) $(LLVM_SRC) $(BLS384_SLIB) + $(RM) $(OBJ_DIR)/*.d $(OBJ_DIR)/*.o $(EXE_DIR)/*.exe $(GEN_EXE) $(ASM_SRC) $(ASM_OBJ) $(LLVM_SRC) $(BLS384_LIB) $(BLS384_SLIB) ALL_SRC=$(SRC_SRC) $(TEST_SRC) $(SAMPLE_SRC) DEPEND_FILE=$(addprefix $(OBJ_DIR)/, $(ALL_SRC:.cpp=.d)) diff --git a/include/bls/bls.hpp b/include/bls/bls.hpp index ca4d0ca..a1aa444 100644 --- a/include/bls/bls.hpp +++ b/include/bls/bls.hpp @@ -7,17 +7,12 @@ http://opensource.org/licenses/BSD-3-Clause */ #include +#include #include #include #include #include -#ifndef BLS_NO_AUTOLINK - #ifdef _MSC_VER - #pragma comment(lib, "bls.lib") - #endif -#endif - namespace bls { // same value with IoMode of mcl/op.hpp @@ -25,18 +20,11 @@ enum { IoBin = 2, // binary number IoDec = 10, // decimal number IoHex = 16, // hexadecimal number - IoFixedByteSeq = 512 // fixed byte representation + IoPrefix = 128, // append '0b'(bin) or '0x'(hex) + IoSerialize = 512, + IoFixedByteSeq = IoSerialize // fixed byte representation }; -namespace impl { - -struct SecretKey; -struct PublicKey; -struct Signature; -struct Id; - -} // bls::impl - /* BLS signature e : G2 x G1 -> Fp12 @@ -55,24 +43,42 @@ struct Id; @param maxUnitSize [in] 4 or 6 (specify same value used in compiling for validation) @note init() is not thread safe */ -void init(int curve = mclBn_CurveFp254BNb, int maxUnitSize = MCLBN_FP_UNIT_SIZE); -size_t getOpUnitSize(); -void getCurveOrder(std::string& str); -void getFieldOrder(std::string& str); -int getG1ByteSize(); -int getFrByteSize(); +inline void init(int curve = mclBn_CurveFp254BNb, int maxUnitSize = MCLBN_FP_UNIT_SIZE) +{ + if (blsInit(curve, maxUnitSize) != 0) throw std::invalid_argument("blsInit"); +} +inline size_t getOpUnitSize() { return blsGetOpUnitSize(); } -class SecretKey; -class PublicKey; -class Signature; -class Id; +inline void getCurveOrder(std::string& str) +{ + str.resize(1024); + mclSize n = blsGetCurveOrder(&str[0], str.size()); + if (n == 0) throw std::runtime_error("blsGetCurveOrder"); + str.resize(n); +} +inline void getFieldOrder(std::string& str) +{ + str.resize(1024); + mclSize n = blsGetFieldOrder(&str[0], str.size()); + if (n == 0) throw std::runtime_error("blsGetFieldOrder"); + str.resize(n); +} +inline int getG1ByteSize() { return blsGetG1ByteSize(); } +inline int getFrByteSize() { return blsGetFrByteSize(); } +namespace local { /* the value of secretKey and Id must be less than r = 0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d sizeof(uint64_t) * keySize byte */ const size_t keySize = MCLBN_FP_UNIT_SIZE; +} + +class SecretKey; +class PublicKey; +class Signature; +class Id; typedef std::vector SecretKeyVec; typedef std::vector PublicKeyVec; @@ -83,25 +89,59 @@ class Id { blsId self_; friend class PublicKey; friend class SecretKey; - template friend struct WrapArray; - impl::Id& getInner() { return *reinterpret_cast(this); } - const impl::Id& getInner() const { return *reinterpret_cast(this); } + friend class Signature; public: - Id(unsigned int id = 0); - bool operator==(const Id& rhs) const; + Id(unsigned int id = 0) + { + blsIdSetInt(&self_, id); + } + bool operator==(const Id& rhs) const + { + return blsIdIsEqual(&self_, &rhs.self_) == 1; + } bool operator!=(const Id& rhs) const { return !(*this == rhs); } - friend std::ostream& operator<<(std::ostream& os, const Id& id); - friend std::istream& operator>>(std::istream& is, Id& id); - void getStr(std::string& str, int ioMode = 0) const; - void setStr(const std::string& str, int ioMode = 0); - bool isZero() const; + friend std::ostream& operator<<(std::ostream& os, const Id& id) + { + std::string str; + id.getStr(str, 16|IoPrefix); + return os << str; + } + friend std::istream& operator>>(std::istream& is, Id& id) + { + std::string str; + is >> str; + id.setStr(str, 16); + return is; + } + void getStr(std::string& str, int ioMode = 0) const + { + str.resize(1024); + size_t n = mclBnFr_getStr(&str[0], str.size(), &self_.v, ioMode); + if (n == 0) throw std::runtime_error("mclBnFr_getStr"); + str.resize(n); + } + void setStr(const std::string& str, int ioMode = 0) + { + int ret = mclBnFr_setStr(&self_.v, str.c_str(), str.size(), ioMode); + if (ret != 0) throw std::runtime_error("mclBnFr_setStr"); + } + bool isZero() const + { + return mclBnFr_isZero(&self_.v) == 1; + } /* set p[0, .., keySize) @note the value must be less than r */ - void set(const uint64_t *p); + void set(const uint64_t *p) + { + setLittleEndian(p, local::keySize * sizeof(uint64_t)); + } // bufSize is truncted/zero extended to keySize - void setLittleEndian(const void *buf, size_t bufSize); + void setLittleEndian(const void *buf, size_t bufSize) + { + mclBnFr_setLittleEndian(&self_.v, buf, bufSize); + } }; /* @@ -109,30 +149,64 @@ public: */ class SecretKey { blsSecretKey self_; - template friend struct WrapArray; - impl::SecretKey& getInner() { return *reinterpret_cast(this); } - const impl::SecretKey& getInner() const { return *reinterpret_cast(this); } public: - SecretKey() : self_() {} - bool operator==(const SecretKey& rhs) const; + bool operator==(const SecretKey& rhs) const + { + return blsSecretKeyIsEqual(&self_, &rhs.self_) == 1; + } bool operator!=(const SecretKey& rhs) const { return !(*this == rhs); } - friend std::ostream& operator<<(std::ostream& os, const SecretKey& sec); - friend std::istream& operator>>(std::istream& is, SecretKey& sec); - void getStr(std::string& str, int ioMode = 0) const; - void setStr(const std::string& str, int ioMode = 0); + friend std::ostream& operator<<(std::ostream& os, const SecretKey& sec) + { + std::string str; + sec.getStr(str, 16|IoPrefix); + return os << str; + } + friend std::istream& operator>>(std::istream& is, SecretKey& sec) + { + std::string str; + is >> str; + sec.setStr(str); + return is; + } + void getStr(std::string& str, int ioMode = 0) const + { + str.resize(1024); + size_t n = mclBnFr_getStr(&str[0], str.size(), &self_.v, ioMode); + if (n == 0) throw std::runtime_error("mclBnFr_getStr"); + str.resize(n); + } + void setStr(const std::string& str, int ioMode = 0) + { + int ret = mclBnFr_setStr(&self_.v, str.c_str(), str.size(), ioMode); + if (ret != 0) throw std::runtime_error("mclBnFr_setStr"); + } /* - initialize secretKey with random number and set id = 0 + initialize secretKey with random number */ - void init(); + void init() + { + int ret = blsSecretKeySetByCSPRNG(&self_); + if (ret != 0) throw std::runtime_error("blsSecretKeySetByCSPRNG"); + } /* set secretKey with p[0, .., keySize) and set id = 0 @note the value must be less than r */ - void set(const uint64_t *p); + void set(const uint64_t *p) + { + setLittleEndian(p, local::keySize * sizeof(uint64_t)); + } // bufSize is truncted/zero extended to keySize - void setLittleEndian(const void *buf, size_t bufSize); + void setLittleEndian(const void *buf, size_t bufSize) + { + mclBnFr_setLittleEndian(&self_.v, buf, bufSize); + } // set hash of buf - void setHashOf(const void *buf, size_t bufSize); + void setHashOf(const void *buf, size_t bufSize) + { + int ret = mclBnFr_setHashOf(&self_.v, buf, bufSize); + if (ret != 0) throw std::runtime_error("mclBnFr_setHashOf"); + } void getPublicKey(PublicKey& pub) const; // constant time sign void sign(Signature& sig, const std::string& m) const; @@ -144,7 +218,15 @@ public: /* make [s_0, ..., s_{k-1}] to prepare k-out-of-n secret sharing */ - void getMasterSecretKey(SecretKeyVec& msk, size_t k) const; + void getMasterSecretKey(SecretKeyVec& msk, size_t k) const + { + if (k <= 1) throw std::invalid_argument("getMasterSecretKey"); + msk.resize(k); + msk[0] = *this; + for (size_t i = 1; i < k; i++) { + msk[i].init(); + } + } /* set a secret key for id > 0 from msk */ @@ -155,7 +237,11 @@ public: /* recover secretKey from k secVec */ - void recover(const SecretKeyVec& secVec, const IdVec& idVec); + void recover(const SecretKeyVec& secVec, const IdVec& idVec) + { + if (secVec.size() != idVec.size()) throw std::invalid_argument("SecretKey::recover"); + recover(secVec.data(), idVec.data(), idVec.size()); + } /* add secret key */ @@ -165,8 +251,16 @@ public: /* the size of msk must be k */ - void set(const SecretKey *msk, size_t k, const Id& id); - void recover(const SecretKey *secVec, const Id *idVec, size_t n); + void set(const SecretKey *msk, size_t k, const Id& id) + { + int ret = blsSecretKeyShare(&self_, &msk->self_, k, &id.self_); + if (ret != 0) throw std::runtime_error("blsSecretKeyShare"); + } + void recover(const SecretKey *secVec, const Id *idVec, size_t n) + { + int ret = blsSecretKeyRecover(&self_, &secVec->self_, &idVec->self_, n); + if (ret != 0) throw std::runtime_error("blsSecretKeyRecover:same id"); + } }; /* @@ -176,17 +270,46 @@ class PublicKey { blsPublicKey self_; friend class SecretKey; friend class Signature; - template friend struct WrapArray; - impl::PublicKey& getInner() { return *reinterpret_cast(this); } - const impl::PublicKey& getInner() const { return *reinterpret_cast(this); } public: - PublicKey() : self_() {} - bool operator==(const PublicKey& rhs) const; + bool operator==(const PublicKey& rhs) const + { + return blsPublicKeyIsEqual(&self_, &rhs.self_) == 1; + } bool operator!=(const PublicKey& rhs) const { return !(*this == rhs); } - friend std::ostream& operator<<(std::ostream& os, const PublicKey& pub); - friend std::istream& operator>>(std::istream& is, PublicKey& pub); - void getStr(std::string& str, int ioMode = 0) const; - void setStr(const std::string& str, int ioMode = 0); + friend std::ostream& operator<<(std::ostream& os, const PublicKey& pub) + { + std::string str; + pub.getStr(str, 16|IoPrefix); + return os << str; + } + friend std::istream& operator>>(std::istream& is, PublicKey& pub) + { + std::string str; + is >> str; + if (str != "0") { + // 1 + std::string t; + for (int i = 0; i < 4; i++) { + is >> t; + str += ' '; + str += t; + } + } + pub.setStr(str, 16); + return is; + } + void getStr(std::string& str, int ioMode = 0) const + { + str.resize(1024); + size_t n = mclBnG2_getStr(&str[0], str.size(), &self_.v, ioMode); + if (n == 0) throw std::runtime_error("mclBnG2_getStr"); + str.resize(n); + } + void setStr(const std::string& str, int ioMode = 0) + { + int ret = mclBnG2_setStr(&self_.v, str.c_str(), str.size(), ioMode); + if (ret != 0) throw std::runtime_error("mclBnG2_setStr"); + } /* set public for id from mpk */ @@ -197,15 +320,30 @@ public: /* recover publicKey from k pubVec */ - void recover(const PublicKeyVec& pubVec, const IdVec& idVec); + void recover(const PublicKeyVec& pubVec, const IdVec& idVec) + { + if (pubVec.size() != idVec.size()) throw std::invalid_argument("PublicKey::recover"); + recover(pubVec.data(), idVec.data(), idVec.size()); + } /* add public key */ - void add(const PublicKey& rhs); + void add(const PublicKey& rhs) + { + blsPublicKeyAdd(&self_, &rhs.self_); + } // the following methods are for C api - void set(const PublicKey *mpk, size_t k, const Id& id); - void recover(const PublicKey *pubVec, const Id *idVec, size_t n); + void set(const PublicKey *mpk, size_t k, const Id& id) + { + int ret = blsPublicKeyShare(&self_, &mpk->self_, k, &id.self_); + if (ret != 0) throw std::runtime_error("blsPublicKeyShare"); + } + void recover(const PublicKey *pubVec, const Id *idVec, size_t n) + { + int ret = blsPublicKeyRecover(&self_, &pubVec->self_, &idVec->self_, n); + if (ret != 0) throw std::runtime_error("blsPublicKeyRecover"); + } }; /* @@ -214,33 +352,81 @@ public: class Signature { blsSignature self_; friend class SecretKey; - template friend struct WrapArray; - impl::Signature& getInner() { return *reinterpret_cast(this); } - const impl::Signature& getInner() const { return *reinterpret_cast(this); } public: - Signature() : self_() {} - bool operator==(const Signature& rhs) const; + bool operator==(const Signature& rhs) const + { + return blsSignatureIsEqual(&self_, &rhs.self_) == 1; + } bool operator!=(const Signature& rhs) const { return !(*this == rhs); } - friend std::ostream& operator<<(std::ostream& os, const Signature& s); - friend std::istream& operator>>(std::istream& is, Signature& s); - void getStr(std::string& str, int ioMode = 0) const; - void setStr(const std::string& str, int ioMode = 0); - bool verify(const PublicKey& pub, const std::string& m) const; + friend std::ostream& operator<<(std::ostream& os, const Signature& sig) + { + std::string str; + sig.getStr(str, 16|IoPrefix); + return os << str; + } + friend std::istream& operator>>(std::istream& is, Signature& sig) + { + std::string str; + is >> str; + if (str != "0") { + // 1 + std::string t; + for (int i = 0; i < 2; i++) { + is >> t; + str += ' '; + str += t; + } + } + sig.setStr(str, 16); + return is; + } + void getStr(std::string& str, int ioMode = 0) const + { + str.resize(1024); + size_t n = mclBnG1_getStr(&str[0], str.size(), &self_.v, ioMode); + if (n == 0) throw std::runtime_error("mclBnG1_getStr"); + str.resize(n); + } + void setStr(const std::string& str, int ioMode = 0) + { + int ret = mclBnG1_setStr(&self_.v, str.c_str(), str.size(), ioMode); + if (ret != 0) throw std::runtime_error("mclBnG1_setStr"); + } + bool verify(const PublicKey& pub, const std::string& m) const + { + return blsVerify(&self_, &pub.self_, m.c_str(), m.size()) == 1; + } /* verify self(pop) with pub */ - bool verify(const PublicKey& pub) const; + bool verify(const PublicKey& pub) const + { + std::string str; + pub.getStr(str); + return verify(pub, str); + } /* recover sig from k sigVec */ - void recover(const SignatureVec& sigVec, const IdVec& idVec); + void recover(const SignatureVec& sigVec, const IdVec& idVec) + { + if (sigVec.size() != idVec.size()) throw std::invalid_argument("Signature::recover"); + recover(sigVec.data(), idVec.data(), idVec.size()); + } /* add signature */ - void add(const Signature& rhs); + void add(const Signature& rhs) + { + blsSignatureAdd(&self_, &rhs.self_); + } // the following methods are for C api - void recover(const Signature* sigVec, const Id *idVec, size_t n); + void recover(const Signature* sigVec, const Id *idVec, size_t n) + { + int ret = blsSignatureRecover(&self_, &sigVec->self_, &idVec->self_, n); + if (ret != 0) throw std::runtime_error("blsSignatureRecover:same id"); + } }; /* @@ -255,6 +441,23 @@ inline void getMasterPublicKey(PublicKeyVec& mpk, const SecretKeyVec& msk) } } +inline void SecretKey::getPublicKey(PublicKey& pub) const +{ + blsGetPublicKey(&pub.self_, &self_); +} +inline void SecretKey::sign(Signature& sig, const std::string& m) const +{ + blsSign(&sig.self_, &self_, m.c_str(), m.size()); +} +inline void SecretKey::getPop(Signature& pop) const +{ + PublicKey pub; + getPublicKey(pub); + std::string m; + pub.getStr(m); + sign(pop, m); +} + /* make pop from msk and mpk */ diff --git a/mklib.bat b/mklib.bat index fb5ae08..a7e5c33 100644 --- a/mklib.bat +++ b/mklib.bat @@ -15,6 +15,4 @@ if "%1"=="dll" ( cl /c %CFLAGS% /Foobj/bls_c.obj src/bls_c.cpp cl /c %CFLAGS% /Foobj/fp.obj ../mcl/src/fp.cpp /DMCLBN_DONT_EXPORT lib /OUT:lib/bls384.lib /nodefaultlib obj/bls_c.obj obj/fp.obj %LDFLAGS% - cl /c %CFLAGS% /Foobj/bls.obj src/bls.cpp - lib /OUT:lib/bls.lib /nodefaultlib obj/bls.obj obj/fp.obj %LDFLAGS% ) diff --git a/readme.md b/readme.md index a2d6d52..cdd0593 100644 --- a/readme.md +++ b/readme.md @@ -10,19 +10,20 @@ Create a working directory (e.g., work) and clone the following repositories. ``` mkdir work cd work -git clone git://github.com/herumi/xbyak.git -git clone git://github.com/herumi/cybozulib.git git clone git://github.com/herumi/mcl.git git clone git://github.com/herumi/bls.git git clone git://github.com/herumi/cybozulib_ext ; for only Windows ``` +# **REMARK** libbls.a is removed +Link `lib/libbls256.a` or `lib/libbls384.a` to use `bls/bls.hpp` according to MCLBN_FP_UNIT_SIZE = 4 or 6. + # Build and test for Linux Specifiy UNIT=4 or 6 always to make. Default UNIT is 6. -To make lib/libbls.a and test, run +To make and test, run ``` cd bls -make test UNIT=4 +make test ``` To make sample programs, run ``` diff --git a/setvar.bat b/setvar.bat index 4c1fbf2..5e1a1c3 100755 --- a/setvar.bat +++ b/setvar.bat @@ -1,7 +1,7 @@ @echo off call ..\mcl\setvar.bat set MCLBN_FP_UNIT_SIZE=6 -set CFLAGS=%CFLAGS% /DMCLBN_FP_UNIT_SIZE=%MCLBN_FP_UNIT_SIZE% /I ..\mcl\include +set CFLAGS=%CFLAGS% /DMCLBN_FP_UNIT_SIZE=%MCLBN_FP_UNIT_SIZE% /I ..\mcl\include /I .\ set LDFLAGS=%LDFLAGS% /LIBPATH:..\mcl\lib echo CFLAGS=%CFLAGS% echo LDFLAGS=%LDFLAGS% \ No newline at end of file diff --git a/src/bls.cpp b/src/bls.cpp deleted file mode 100644 index d83b259..0000000 --- a/src/bls.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/** - @file - @author MITSUNARI Shigeo(@herumi) - @license modified new BSD license - http://opensource.org/licenses/BSD-3-Clause -*/ -#include -#include -#include -#define MCLBN_NO_AUTOLINK -#include -#if MCLBN_FP_UNIT_SIZE == 4 -#include -using namespace mcl::bn256; -#elif MCLBN_FP_UNIT_SIZE == 6 -#include -using namespace mcl::bn384; -#else - #error "define MCLBN_FP_UNIT_SIZE 4(or 6)" -#endif - -typedef std::vector FrVec; -const std::vector *g_pQcoeff; -const G2 *g_pQ; - -namespace bls { - -static const G2& getQ() { return *g_pQ; } -static const std::vector& getQcoeff() { return *g_pQcoeff; } - -static void HashAndMapToG1(G1& P, const std::string& m) -{ - Fp t; - t.setHashOf(m); - mapToG1(P, t); -} - -template -void evalPoly(G& y, const T& x, const Vec& c) -{ - if (c.size() < 2) throw cybozu::Exception("bls:evalPoly:bad size") << c.size(); - y = c[c.size() - 1]; - for (int i = (int)c.size() - 2; i >= 0; i--) { - G::mul(y, y, x); - G::add(y, y, c[i]); - } -} - -template -struct WrapArray { - const T *v; - size_t k; - WrapArray(const T *v, size_t k) : v(v), k(k) {} - const G& operator[](size_t i) const - { - return v[i].getInner().get(); - } - size_t size() const { return k; } -}; - -struct Polynomial { - FrVec c; // f[x] = sum_{i=0}^{k-1} c[i] x^i - void init(const Fr& s, int k) - { - if (k < 2) throw cybozu::Exception("bls:Polynomial:init:bad k") << k; - c.resize(k); - c[0] = s; - for (size_t i = 1; i < c.size(); i++) { - c[i].setRand(); - } - } - // y = f(id) - void eval(Fr& y, const Fr& id) const - { - if (id.isZero()) throw cybozu::Exception("bls:Polynomial:eval:id is zero"); - evalPoly(y, id, c); - } -}; - -namespace impl { - -struct Id { - Fr v; - const Fr& get() const { return v; } -}; - -struct SecretKey { - Fr s; - const Fr& get() const { return s; } -}; - -struct Signature { - G1 sHm; // s Hash(m) - const G1& get() const { return sHm; } -}; - -struct PublicKey { - G2 sQ; - const G2& get() const { return sQ; } - void getStr(std::string& str) const - { - sQ.getStr(str, mcl::IoArrayRaw); - } -}; - -} // mcl::bls::impl - -/* - recover f(0) by { (x, y) | x = S[i], y = f(x) = vec[i] } -*/ -template -void LagrangeInterpolation(G& r, const V1& vec, const V2& S) -{ - /* - delta_{i,S}(0) = prod_{j != i} S[j] / (S[j] - S[i]) = a / b - where a = prod S[j], b = S[i] * prod_{j != i} (S[j] - S[i]) - */ - const size_t k = S.size(); - if (vec.size() != k) throw cybozu::Exception("bls:LagrangeInterpolation:bad size") << vec.size() << k; - if (k < 2) throw cybozu::Exception("bls:LagrangeInterpolation:too small size") << k; - FrVec delta(k); - Fr a = S[0]; - for (size_t i = 1; i < k; i++) { - a *= S[i]; - } - for (size_t i = 0; i < k; i++) { - Fr b = S[i]; - for (size_t j = 0; j < k; j++) { - if (j != i) { - Fr v = S[j] - S[i]; - if (v.isZero()) throw cybozu::Exception("bls:LagrangeInterpolation:S has same id") << i << j; - b *= v; - } - } - delta[i] = a / b; - } - - /* - f(0) = sum_i f(S[i]) delta_{i,S}(0) - */ - r.clear(); - G t; - for (size_t i = 0; i < delta.size(); i++) { - G::mul(t, vec[i], delta[i]); - r += t; - } -} - -template -std::ostream& writeAsHex(std::ostream& os, const T& t) -{ - std::string str; - t.getStr(str, mcl::IoHexPrefix); - return os << str; -} - -void init(int curve, int maxUnitSize) -{ - if (maxUnitSize != MCLBN_FP_UNIT_SIZE) throw cybozu::Exception("bls:init:bad maxUnitSize") << maxUnitSize << MCLBN_FP_UNIT_SIZE; - mcl::CurveParam cp; - switch (curve) { - case MCL_BN254: - cp = mcl::BN254; - break; -#if MCLBN_FP_UNIT_SIZE == 6 - case MCL_BN381_1: - cp = mcl::BN381_1; - break; - case MCL_BLS12_381: - cp = mcl::BLS12_381; - break; -#endif - default: - throw cybozu::Exception("bls:init:bad curve") << curve; - } - initPairing(cp); - assert(sizeof(Id) == sizeof(impl::Id)); - assert(sizeof(SecretKey) == sizeof(impl::SecretKey)); - assert(sizeof(PublicKey) == sizeof(impl::PublicKey)); - assert(sizeof(Signature) == sizeof(impl::Signature)); - static G2 Q; - if (curve == mclBn_CurveFp254BNb) { - Q.set( - Fp2("12723517038133731887338407189719511622662176727675373276651903807414909099441", "4168783608814932154536427934509895782246573715297911553964171371032945126671"), - Fp2("13891744915211034074451795021214165905772212241412891944830863846330766296736", "7937318970632701341203597196594272556916396164729705624521405069090520231616") - ); - } else { - mapToG2(Q, 1); - } - static std::vector Qcoeff; - - precomputeG2(Qcoeff, Q); - g_pQ = &Q; - g_pQcoeff = &Qcoeff; -} -size_t getOpUnitSize() -{ - return Fp::getUnitSize() * sizeof(mcl::fp::Unit) / sizeof(uint64_t); -} - -void getCurveOrder(std::string& str) -{ - Fr::getModulo(str); -} -void getFieldOrder(std::string& str) -{ - Fp::getModulo(str); -} - -int getG1ByteSize() -{ - return (int)Fp::getByteSize(); -} - -int getFrByteSize() -{ - return (int)Fr::getByteSize(); -} - -Id::Id(unsigned int id) -{ - getInner().v = id; -} - -bool Id::operator==(const Id& rhs) const -{ - return getInner().v == rhs.getInner().v; -} - -std::ostream& operator<<(std::ostream& os, const Id& id) -{ - return writeAsHex(os, id.getInner().v); -} - -std::istream& operator>>(std::istream& is, Id& id) -{ - return is >> id.getInner().v; -} -void Id::getStr(std::string& str, int ioMode) const -{ - getInner().v.getStr(str, ioMode); -} -void Id::setStr(const std::string& str, int ioMode) -{ - getInner().v.setStr(str, ioMode); -} - -bool Id::isZero() const -{ - return getInner().v.isZero(); -} - -void Id::set(const uint64_t *p) -{ - getInner().v.setArrayMask(p, keySize); -} - -void Id::setLittleEndian(const void *buf, size_t bufSize) -{ - getInner().v.setArrayMask((const char *)buf, bufSize); -} - -bool Signature::operator==(const Signature& rhs) const -{ - return getInner().sHm == rhs.getInner().sHm; -} - -std::ostream& operator<<(std::ostream& os, const Signature& s) -{ - return writeAsHex(os, s.getInner().sHm); -} - -std::istream& operator>>(std::istream& os, Signature& s) -{ - return os >> s.getInner().sHm; -} -void Signature::getStr(std::string& str, int ioMode) const -{ - getInner().sHm.getStr(str, ioMode); -} -void Signature::setStr(const std::string& str, int ioMode) -{ - getInner().sHm.setStr(str, ioMode); -} - -bool Signature::verify(const PublicKey& pub, const std::string& m) const -{ - G1 Hm; - HashAndMapToG1(Hm, m); // Hm = Hash(m) -#if 1 - /* - e(P1, Q1) == e(P2, Q2) - <=> finalExp(ML(P1, Q1)) == finalExp(ML(P2, Q2)) - <=> finalExp(ML(P1, Q1) / ML(P2, Q2)) == 1 - <=> finalExp(ML(P1, Q1) * ML(-P2, Q2)) == 1 - 2.1Mclk => 1.5Mclk - */ - Fp12 e; - std::vector Q2coeff; - precomputeG2(Q2coeff, pub.getInner().sQ); - precomputedMillerLoop2(e, getInner().sHm, getQcoeff(), -Hm, Q2coeff); - finalExp(e, e); - return e.isOne(); -#else - Fp12 e1, e2; - pairing(e1, getInner().sHm, getQ()); // e(s Hm, Q) - pairing(e2, Hm, pub.getInner().sQ); // e(Hm, sQ) - return e1 == e2; -#endif -} - -bool Signature::verify(const PublicKey& pub) const -{ - std::string str; - pub.getInner().sQ.getStr(str); - return verify(pub, str); -} - -void Signature::recover(const SignatureVec& sigVec, const IdVec& idVec) -{ - if (sigVec.size() != idVec.size()) throw cybozu::Exception("Signature:recover:bad size") << sigVec.size() << idVec.size(); - recover(sigVec.data(), idVec.data(), sigVec.size()); -} - -void Signature::recover(const Signature* sigVec, const Id *idVec, size_t n) -{ - WrapArray signW(sigVec, n); - WrapArray idW(idVec, n); - LagrangeInterpolation(getInner().sHm, signW, idW); -} - -void Signature::add(const Signature& rhs) -{ - getInner().sHm += rhs.getInner().sHm; -} - -bool PublicKey::operator==(const PublicKey& rhs) const -{ - return getInner().sQ == rhs.getInner().sQ; -} - -std::ostream& operator<<(std::ostream& os, const PublicKey& pub) -{ - return writeAsHex(os, pub.getInner().sQ); -} - -std::istream& operator>>(std::istream& is, PublicKey& pub) -{ - return is >> pub.getInner().sQ; -} - -void PublicKey::getStr(std::string& str, int ioMode) const -{ - getInner().sQ.getStr(str, ioMode); -} -void PublicKey::setStr(const std::string& str, int ioMode) -{ - getInner().sQ.setStr(str, ioMode); -} -void PublicKey::set(const PublicKey *mpk, size_t k, const Id& id) -{ - WrapArray w(mpk, k); - evalPoly(getInner().sQ, id.getInner().v, w); -} - -void PublicKey::recover(const PublicKeyVec& pubVec, const IdVec& idVec) -{ - if (pubVec.size() != idVec.size()) throw cybozu::Exception("PublicKey:recover:bad size") << pubVec.size() << idVec.size(); - recover(pubVec.data(), idVec.data(), pubVec.size()); -} -void PublicKey::recover(const PublicKey *pubVec, const Id *idVec, size_t n) -{ - WrapArray pubW(pubVec, n); - WrapArray idW(idVec, n); - LagrangeInterpolation(getInner().sQ, pubW, idW); -} - -void PublicKey::add(const PublicKey& rhs) -{ - getInner().sQ += rhs.getInner().sQ; -} - -bool SecretKey::operator==(const SecretKey& rhs) const -{ - return getInner().s == rhs.getInner().s; -} - -std::ostream& operator<<(std::ostream& os, const SecretKey& sec) -{ - return writeAsHex(os, sec.getInner().s); -} - -std::istream& operator>>(std::istream& is, SecretKey& sec) -{ - return is >> sec.getInner().s; -} -void SecretKey::getStr(std::string& str, int ioMode) const -{ - getInner().s.getStr(str, ioMode); -} -void SecretKey::setStr(const std::string& str, int ioMode) -{ - getInner().s.setStr(str, ioMode); -} - -void SecretKey::init() -{ - getInner().s.setRand(); -} - -void SecretKey::set(const uint64_t *p) -{ - getInner().s.setArrayMask(p, keySize); -} -void SecretKey::setLittleEndian(const void *buf, size_t bufSize) -{ - getInner().s.setArrayMask((const char *)buf, bufSize); -} -void SecretKey::setHashOf(const void *buf, size_t bufSize) -{ - getInner().s.setHashOf(buf, bufSize); -} - -void SecretKey::getPublicKey(PublicKey& pub) const -{ - G2::mul(pub.getInner().sQ, getQ(), getInner().s); -} - -void SecretKey::sign(Signature& sig, const std::string& m) const -{ - G1 Hm; - HashAndMapToG1(Hm, m); -// G1::mul(sig.getInner().sHm, Hm, getInner().s); - G1::mulCT(sig.getInner().sHm, Hm, getInner().s); -} - -void SecretKey::getPop(Signature& pop) const -{ - PublicKey pub; - getPublicKey(pub); - std::string m; - pub.getInner().sQ.getStr(m); - sign(pop, m); -} - -void SecretKey::getMasterSecretKey(SecretKeyVec& msk, size_t k) const -{ - if (k <= 1) throw cybozu::Exception("bls:SecretKey:getMasterSecretKey:bad k") << k; - msk.resize(k); - msk[0] = *this; - for (size_t i = 1; i < k; i++) { - msk[i].init(); - } -} - -void SecretKey::set(const SecretKey *msk, size_t k, const Id& id) -{ - WrapArray w(msk, k); - evalPoly(getInner().s, id.getInner().v, w); -} - -void SecretKey::recover(const SecretKeyVec& secVec, const IdVec& idVec) -{ - if (secVec.size() != idVec.size()) throw cybozu::Exception("SecretKey:recover:bad size") << secVec.size() << idVec.size(); - recover(secVec.data(), idVec.data(), secVec.size()); -} -void SecretKey::recover(const SecretKey *secVec, const Id *idVec, size_t n) -{ - WrapArray secW(secVec, n); - WrapArray idW(idVec, n); - LagrangeInterpolation(getInner().s, secW, idW); -} - -void SecretKey::add(const SecretKey& rhs) -{ - getInner().s += rhs.getInner().s; -} - -} // bls diff --git a/src/bls_c.cpp b/src/bls_c.cpp deleted file mode 100644 index 75e5a44..0000000 --- a/src/bls_c.cpp +++ /dev/null @@ -1,414 +0,0 @@ -#define MCLBN_DONT_EXPORT -#define BLS_DLL_EXPORT - -#include - -#include "../mcl/src/bn_c_impl.hpp" - -/* - BLS signature - e : G1 x G2 -> Fp12 - Q in G2 ; fixed global parameter - H : {str} -> G1 - s : secret key - sQ ; public key - s H(m) ; signature of m - verify ; e(sQ, H(m)) = e(Q, s H(m)) -*/ - -static G2 g_Q; -const size_t maxQcoeffN = 128; -static mcl::FixedArray g_Qcoeff; // precomputed Q -inline const G2& getQ() { return g_Q; } -inline const mcl::FixedArray& getQcoeff() { return g_Qcoeff; } - -int blsInitNotThreadSafe(int curve, int maxUnitSize) -{ - int ret = mclBn_init(curve, maxUnitSize); - if (ret < 0) return ret; - bool b; - - if (curve == MCL_BN254) { - const char *Qx_BN254 = "11ccb44e77ac2c5dc32a6009594dbe331ec85a61290d6bbac8cc7ebb2dceb128 f204a14bbdac4a05be9a25176de827f2e60085668becdd4fc5fa914c9ee0d9a"; - const char *Qy_BN254 = "7c13d8487903ee3c1c5ea327a3a52b6cc74796b1760d5ba20ed802624ed19c8 8f9642bbaacb73d8c89492528f58932f2de9ac3e80c7b0e41f1a84f1c40182"; - g_Q.x.setStr(&b, Qx_BN254, 16); - g_Q.y.setStr(&b, Qy_BN254, 16); - g_Q.z = 1; - } else { - mapToG2(&b, g_Q, 1); - } - if (!b) return -100; - if (curve == MCL_BN254) { - #include "./qcoeff-bn254.hpp" - g_Qcoeff.resize(BN::param.precomputedQcoeffSize); - assert(g_Qcoeff.size() == CYBOZU_NUM_OF_ARRAY(tbl)); - for (size_t i = 0; i < g_Qcoeff.size(); i++) { - Fp6& x6 = g_Qcoeff[i]; - for (size_t j = 0; j < 6; j++) { - Fp& x = x6.getFp0()[j]; - mcl::fp::Unit *p = const_cast(x.getUnit()); - for (size_t k = 0; k < 4; k++) { - p[k] = QcoeffTblBN254[i][j][k]; - } - } - } - } else { - precomputeG2(&b, g_Qcoeff, getQ()); - } - if (!b) return -101; - return 0; -} - -#ifdef __EMSCRIPTEN__ -extern "C" BLS_DLL_API void *blsMalloc(size_t n) -{ - return malloc(n); -} -extern "C" BLS_DLL_API void blsFree(void *p) -{ - free(p); -} -#endif - -#if !defined(__EMSCRIPTEN__) && !defined(__wasm__) - #if defined(CYBOZU_CPP_VERSION) && CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 - #include - #define USE_STD_MUTEX - #else - #include - #define USE_CYBOZU_MUTEX - #endif -#endif - -int blsInit(int curve, int maxUnitSize) -{ - int ret = 0; -#ifdef USE_STD_MUTEX - static std::mutex m; - std::lock_guard lock(m); -#elif defined(USE_CYBOZU_MUTEX) - static cybozu::Mutex m; - cybozu::AutoLock lock(m); -#endif - static int g_curve = -1; - if (g_curve != curve) { - ret = blsInitNotThreadSafe(curve, maxUnitSize); - g_curve = curve; - } - return ret; -} - -static inline const mclBnG1 *cast(const G1* x) { return (const mclBnG1*)x; } -static inline const mclBnG2 *cast(const G2* x) { return (const mclBnG2*)x; } - -void blsIdSetInt(blsId *id, int x) -{ - mclBnFr_setInt(&id->v, x); -} - -int blsSecretKeySetLittleEndian(blsSecretKey *sec, const void *buf, mclSize bufSize) -{ - return mclBnFr_setLittleEndian(&sec->v, buf, bufSize); -} - -void blsGetPublicKey(blsPublicKey *pub, const blsSecretKey *sec) -{ - mclBnG2_mul(&pub->v, cast(&getQ()), &sec->v); -} - -void blsSign(blsSignature *sig, const blsSecretKey *sec, const void *m, mclSize size) -{ - G1 Hm; - hashAndMapToG1(Hm, m, size); - mclBnG1_mulCT(&sig->v, cast(&Hm), &sec->v); -} - -/* - e(P1, Q1) == e(P2, Q2) - <=> finalExp(ML(P1, Q1)) == finalExp(ML(P2, Q2)) - <=> finalExp(ML(P1, Q1) / ML(P2, Q2)) == 1 - <=> finalExp(ML(P1, Q1) * ML(-P2, Q2)) == 1 - Q1 is precomputed -*/ -bool isEqualTwoPairings(const G1& P1, const Fp6* Q1coeff, const G1& P2, const G2& Q2) -{ - Fp12 e; - precomputedMillerLoop2mixed(e, P2, Q2, -P1, Q1coeff); - finalExp(e, e); - return e.isOne(); -} - -int blsVerify(const blsSignature *sig, const blsPublicKey *pub, const void *m, mclSize size) -{ - G1 Hm; - hashAndMapToG1(Hm, m, size); - /* - e(sHm, Q) = e(Hm, sQ) - e(sig, Q) = e(Hm, pub) - */ - return isEqualTwoPairings(*cast(&sig->v), getQcoeff().data(), Hm, *cast(&pub->v)); -} - -mclSize blsIdSerialize(void *buf, mclSize maxBufSize, const blsId *id) -{ - return mclBnFr_serialize(buf, maxBufSize, &id->v); -} - -mclSize blsSecretKeySerialize(void *buf, mclSize maxBufSize, const blsSecretKey *sec) -{ - return mclBnFr_serialize(buf, maxBufSize, &sec->v); -} - -mclSize blsPublicKeySerialize(void *buf, mclSize maxBufSize, const blsPublicKey *pub) -{ - return mclBnG2_serialize(buf, maxBufSize, &pub->v); -} - -mclSize blsSignatureSerialize(void *buf, mclSize maxBufSize, const blsSignature *sig) -{ - return mclBnG1_serialize(buf, maxBufSize, &sig->v); -} - -mclSize blsIdDeserialize(blsId *id, const void *buf, mclSize bufSize) -{ - return mclBnFr_deserialize(&id->v, buf, bufSize); -} - -mclSize blsSecretKeyDeserialize(blsSecretKey *sig, const void *buf, mclSize bufSize) -{ - return mclBnFr_deserialize(&sig->v, buf, bufSize); -} - -mclSize blsPublicKeyDeserialize(blsPublicKey *pub, const void *buf, mclSize bufSize) -{ - return mclBnG2_deserialize(&pub->v, buf, bufSize); -} - -mclSize blsSignatureDeserialize(blsSignature *sig, const void *buf, mclSize bufSize) -{ - return mclBnG1_deserialize(&sig->v, buf, bufSize); -} - -int blsIdIsEqual(const blsId *lhs, const blsId *rhs) -{ - return mclBnFr_isEqual(&lhs->v, &rhs->v); -} - -int blsSecretKeyIsEqual(const blsSecretKey *lhs, const blsSecretKey *rhs) -{ - return mclBnFr_isEqual(&lhs->v, &rhs->v); -} - -int blsPublicKeyIsEqual(const blsPublicKey *lhs, const blsPublicKey *rhs) -{ - return mclBnG2_isEqual(&lhs->v, &rhs->v); -} - -int blsSignatureIsEqual(const blsSignature *lhs, const blsSignature *rhs) -{ - return mclBnG1_isEqual(&lhs->v, &rhs->v); -} - -int blsSecretKeyShare(blsSecretKey *sec, const blsSecretKey* msk, mclSize k, const blsId *id) -{ - return mclBn_FrEvaluatePolynomial(&sec->v, &msk->v, k, &id->v); -} - -int blsPublicKeyShare(blsPublicKey *pub, const blsPublicKey *mpk, mclSize k, const blsId *id) -{ - return mclBn_G2EvaluatePolynomial(&pub->v, &mpk->v, k, &id->v); -} - -int blsSecretKeyRecover(blsSecretKey *sec, const blsSecretKey *secVec, const blsId *idVec, mclSize n) -{ - return mclBn_FrLagrangeInterpolation(&sec->v, &idVec->v, &secVec->v, n); -} - -int blsPublicKeyRecover(blsPublicKey *pub, const blsPublicKey *pubVec, const blsId *idVec, mclSize n) -{ - return mclBn_G2LagrangeInterpolation(&pub->v, &idVec->v, &pubVec->v, n); -} - -int blsSignatureRecover(blsSignature *sig, const blsSignature *sigVec, const blsId *idVec, mclSize n) -{ - return mclBn_G1LagrangeInterpolation(&sig->v, &idVec->v, &sigVec->v, n); -} - -void blsSecretKeyAdd(blsSecretKey *sec, const blsSecretKey *rhs) -{ - mclBnFr_add(&sec->v, &sec->v, &rhs->v); -} - -void blsPublicKeyAdd(blsPublicKey *pub, const blsPublicKey *rhs) -{ - mclBnG2_add(&pub->v, &pub->v, &rhs->v); -} - -void blsSignatureAdd(blsSignature *sig, const blsSignature *rhs) -{ - mclBnG1_add(&sig->v, &sig->v, &rhs->v); -} - -void blsSignatureVerifyOrder(int doVerify) -{ - mclBn_verifyOrderG1(doVerify); -} -void blsPublicKeyVerifyOrder(int doVerify) -{ - mclBn_verifyOrderG2(doVerify); -} -int blsSignatureIsValidOrder(const blsSignature *sig) -{ - return mclBnG1_isValidOrder(&sig->v); -} -int blsPublicKeyIsValidOrder(const blsPublicKey *pub) -{ - return mclBnG2_isValidOrder(&pub->v); -} - -#ifndef BLS_MINIMUM_API -void blsSecretKeySub(blsSecretKey *sec, const blsSecretKey *rhs) -{ - mclBnFr_sub(&sec->v, &sec->v, &rhs->v); -} - -void blsPublicKeySub(blsPublicKey *pub, const blsPublicKey *rhs) -{ - mclBnG2_sub(&pub->v, &pub->v, &rhs->v); -} - -void blsSignatureSub(blsSignature *sig, const blsSignature *rhs) -{ - mclBnG1_sub(&sig->v, &sig->v, &rhs->v); -} -mclSize blsGetOpUnitSize() // FpUint64Size -{ - return Fp::getUnitSize() * sizeof(mcl::fp::Unit) / sizeof(uint64_t); -} - -int blsGetCurveOrder(char *buf, mclSize maxBufSize) -{ - return (int)Fr::getModulo(buf, maxBufSize); -} - -int blsGetFieldOrder(char *buf, mclSize maxBufSize) -{ - return (int)Fp::getModulo(buf, maxBufSize); -} - -int blsGetG1ByteSize() -{ - return mclBn_getG1ByteSize(); -} - -int blsGetFrByteSize() -{ - return mclBn_getFrByteSize(); -} - -void blsGetGeneratorOfG2(blsPublicKey *pub) -{ - *(G2*)pub = getQ(); -} - -int blsIdSetDecStr(blsId *id, const char *buf, mclSize bufSize) -{ - return mclBnFr_setStr(&id->v, buf, bufSize, 10); -} -int blsIdSetHexStr(blsId *id, const char *buf, mclSize bufSize) -{ - return mclBnFr_setStr(&id->v, buf, bufSize, 16); -} - -int blsIdSetLittleEndian(blsId *id, const void *buf, mclSize bufSize) -{ - return mclBnFr_setLittleEndian(&id->v, buf, bufSize); -} - -mclSize blsIdGetDecStr(char *buf, mclSize maxBufSize, const blsId *id) -{ - return mclBnFr_getStr(buf, maxBufSize, &id->v, 10); -} - -mclSize blsIdGetHexStr(char *buf, mclSize maxBufSize, const blsId *id) -{ - return mclBnFr_getStr(buf, maxBufSize, &id->v, 16); -} - -int blsHashToSecretKey(blsSecretKey *sec, const void *buf, mclSize bufSize) -{ - return mclBnFr_setHashOf(&sec->v, buf, bufSize); -} - -#ifndef MCL_DONT_USE_CSPRNG -int blsSecretKeySetByCSPRNG(blsSecretKey *sec) -{ - return mclBnFr_setByCSPRNG(&sec->v); -} -#endif - -void blsGetPop(blsSignature *sig, const blsSecretKey *sec) -{ - blsPublicKey pub; - blsGetPublicKey(&pub, sec); - char buf[1024]; - mclSize n = mclBnG2_serialize(buf, sizeof(buf), &pub.v); - assert(n); - blsSign(sig, sec, buf, n); -} - -int blsVerifyPop(const blsSignature *sig, const blsPublicKey *pub) -{ - char buf[1024]; - mclSize n = mclBnG2_serialize(buf, sizeof(buf), &pub->v); - if (n == 0) return 0; - return blsVerify(sig, pub, buf, n); -} - -mclSize blsIdGetLittleEndian(void *buf, mclSize maxBufSize, const blsId *id) -{ - return mclBnFr_serialize(buf, maxBufSize, &id->v); -} -int blsSecretKeySetDecStr(blsSecretKey *sec, const char *buf, mclSize bufSize) -{ - return mclBnFr_setStr(&sec->v, buf, bufSize, 10); -} -int blsSecretKeySetHexStr(blsSecretKey *sec, const char *buf, mclSize bufSize) -{ - return mclBnFr_setStr(&sec->v, buf, bufSize, 16); -} -mclSize blsSecretKeyGetLittleEndian(void *buf, mclSize maxBufSize, const blsSecretKey *sec) -{ - return mclBnFr_serialize(buf, maxBufSize, &sec->v); -} -mclSize blsSecretKeyGetDecStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec) -{ - return mclBnFr_getStr(buf, maxBufSize, &sec->v, 10); -} -mclSize blsSecretKeyGetHexStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec) -{ - return mclBnFr_getStr(buf, maxBufSize, &sec->v, 16); -} -int blsPublicKeySetHexStr(blsPublicKey *pub, const char *buf, mclSize bufSize) -{ - return mclBnG2_setStr(&pub->v, buf, bufSize, 16); -} -mclSize blsPublicKeyGetHexStr(char *buf, mclSize maxBufSize, const blsPublicKey *pub) -{ - return mclBnG2_getStr(buf, maxBufSize, &pub->v, 16); -} -int blsSignatureSetHexStr(blsSignature *sig, const char *buf, mclSize bufSize) -{ - return mclBnG1_setStr(&sig->v, buf, bufSize, 16); -} -mclSize blsSignatureGetHexStr(char *buf, mclSize maxBufSize, const blsSignature *sig) -{ - return mclBnG1_getStr(buf, maxBufSize, &sig->v, 16); -} -void blsDHKeyExchange(blsPublicKey *out, const blsSecretKey *sec, const blsPublicKey *pub) -{ - mclBnG2_mulCT(&out->v, &pub->v, &sec->v); -} - -#endif - diff --git a/src/bls_c384.cpp b/src/bls_c384.cpp new file mode 100644 index 0000000..d28f854 --- /dev/null +++ b/src/bls_c384.cpp @@ -0,0 +1,3 @@ +#define MCLBN_FP_UNIT_SIZE 6 +#include "bls_c_impl.hpp" + diff --git a/src/bls_c_impl.hpp b/src/bls_c_impl.hpp new file mode 100644 index 0000000..75e5a44 --- /dev/null +++ b/src/bls_c_impl.hpp @@ -0,0 +1,414 @@ +#define MCLBN_DONT_EXPORT +#define BLS_DLL_EXPORT + +#include + +#include "../mcl/src/bn_c_impl.hpp" + +/* + BLS signature + e : G1 x G2 -> Fp12 + Q in G2 ; fixed global parameter + H : {str} -> G1 + s : secret key + sQ ; public key + s H(m) ; signature of m + verify ; e(sQ, H(m)) = e(Q, s H(m)) +*/ + +static G2 g_Q; +const size_t maxQcoeffN = 128; +static mcl::FixedArray g_Qcoeff; // precomputed Q +inline const G2& getQ() { return g_Q; } +inline const mcl::FixedArray& getQcoeff() { return g_Qcoeff; } + +int blsInitNotThreadSafe(int curve, int maxUnitSize) +{ + int ret = mclBn_init(curve, maxUnitSize); + if (ret < 0) return ret; + bool b; + + if (curve == MCL_BN254) { + const char *Qx_BN254 = "11ccb44e77ac2c5dc32a6009594dbe331ec85a61290d6bbac8cc7ebb2dceb128 f204a14bbdac4a05be9a25176de827f2e60085668becdd4fc5fa914c9ee0d9a"; + const char *Qy_BN254 = "7c13d8487903ee3c1c5ea327a3a52b6cc74796b1760d5ba20ed802624ed19c8 8f9642bbaacb73d8c89492528f58932f2de9ac3e80c7b0e41f1a84f1c40182"; + g_Q.x.setStr(&b, Qx_BN254, 16); + g_Q.y.setStr(&b, Qy_BN254, 16); + g_Q.z = 1; + } else { + mapToG2(&b, g_Q, 1); + } + if (!b) return -100; + if (curve == MCL_BN254) { + #include "./qcoeff-bn254.hpp" + g_Qcoeff.resize(BN::param.precomputedQcoeffSize); + assert(g_Qcoeff.size() == CYBOZU_NUM_OF_ARRAY(tbl)); + for (size_t i = 0; i < g_Qcoeff.size(); i++) { + Fp6& x6 = g_Qcoeff[i]; + for (size_t j = 0; j < 6; j++) { + Fp& x = x6.getFp0()[j]; + mcl::fp::Unit *p = const_cast(x.getUnit()); + for (size_t k = 0; k < 4; k++) { + p[k] = QcoeffTblBN254[i][j][k]; + } + } + } + } else { + precomputeG2(&b, g_Qcoeff, getQ()); + } + if (!b) return -101; + return 0; +} + +#ifdef __EMSCRIPTEN__ +extern "C" BLS_DLL_API void *blsMalloc(size_t n) +{ + return malloc(n); +} +extern "C" BLS_DLL_API void blsFree(void *p) +{ + free(p); +} +#endif + +#if !defined(__EMSCRIPTEN__) && !defined(__wasm__) + #if defined(CYBOZU_CPP_VERSION) && CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 + #include + #define USE_STD_MUTEX + #else + #include + #define USE_CYBOZU_MUTEX + #endif +#endif + +int blsInit(int curve, int maxUnitSize) +{ + int ret = 0; +#ifdef USE_STD_MUTEX + static std::mutex m; + std::lock_guard lock(m); +#elif defined(USE_CYBOZU_MUTEX) + static cybozu::Mutex m; + cybozu::AutoLock lock(m); +#endif + static int g_curve = -1; + if (g_curve != curve) { + ret = blsInitNotThreadSafe(curve, maxUnitSize); + g_curve = curve; + } + return ret; +} + +static inline const mclBnG1 *cast(const G1* x) { return (const mclBnG1*)x; } +static inline const mclBnG2 *cast(const G2* x) { return (const mclBnG2*)x; } + +void blsIdSetInt(blsId *id, int x) +{ + mclBnFr_setInt(&id->v, x); +} + +int blsSecretKeySetLittleEndian(blsSecretKey *sec, const void *buf, mclSize bufSize) +{ + return mclBnFr_setLittleEndian(&sec->v, buf, bufSize); +} + +void blsGetPublicKey(blsPublicKey *pub, const blsSecretKey *sec) +{ + mclBnG2_mul(&pub->v, cast(&getQ()), &sec->v); +} + +void blsSign(blsSignature *sig, const blsSecretKey *sec, const void *m, mclSize size) +{ + G1 Hm; + hashAndMapToG1(Hm, m, size); + mclBnG1_mulCT(&sig->v, cast(&Hm), &sec->v); +} + +/* + e(P1, Q1) == e(P2, Q2) + <=> finalExp(ML(P1, Q1)) == finalExp(ML(P2, Q2)) + <=> finalExp(ML(P1, Q1) / ML(P2, Q2)) == 1 + <=> finalExp(ML(P1, Q1) * ML(-P2, Q2)) == 1 + Q1 is precomputed +*/ +bool isEqualTwoPairings(const G1& P1, const Fp6* Q1coeff, const G1& P2, const G2& Q2) +{ + Fp12 e; + precomputedMillerLoop2mixed(e, P2, Q2, -P1, Q1coeff); + finalExp(e, e); + return e.isOne(); +} + +int blsVerify(const blsSignature *sig, const blsPublicKey *pub, const void *m, mclSize size) +{ + G1 Hm; + hashAndMapToG1(Hm, m, size); + /* + e(sHm, Q) = e(Hm, sQ) + e(sig, Q) = e(Hm, pub) + */ + return isEqualTwoPairings(*cast(&sig->v), getQcoeff().data(), Hm, *cast(&pub->v)); +} + +mclSize blsIdSerialize(void *buf, mclSize maxBufSize, const blsId *id) +{ + return mclBnFr_serialize(buf, maxBufSize, &id->v); +} + +mclSize blsSecretKeySerialize(void *buf, mclSize maxBufSize, const blsSecretKey *sec) +{ + return mclBnFr_serialize(buf, maxBufSize, &sec->v); +} + +mclSize blsPublicKeySerialize(void *buf, mclSize maxBufSize, const blsPublicKey *pub) +{ + return mclBnG2_serialize(buf, maxBufSize, &pub->v); +} + +mclSize blsSignatureSerialize(void *buf, mclSize maxBufSize, const blsSignature *sig) +{ + return mclBnG1_serialize(buf, maxBufSize, &sig->v); +} + +mclSize blsIdDeserialize(blsId *id, const void *buf, mclSize bufSize) +{ + return mclBnFr_deserialize(&id->v, buf, bufSize); +} + +mclSize blsSecretKeyDeserialize(blsSecretKey *sig, const void *buf, mclSize bufSize) +{ + return mclBnFr_deserialize(&sig->v, buf, bufSize); +} + +mclSize blsPublicKeyDeserialize(blsPublicKey *pub, const void *buf, mclSize bufSize) +{ + return mclBnG2_deserialize(&pub->v, buf, bufSize); +} + +mclSize blsSignatureDeserialize(blsSignature *sig, const void *buf, mclSize bufSize) +{ + return mclBnG1_deserialize(&sig->v, buf, bufSize); +} + +int blsIdIsEqual(const blsId *lhs, const blsId *rhs) +{ + return mclBnFr_isEqual(&lhs->v, &rhs->v); +} + +int blsSecretKeyIsEqual(const blsSecretKey *lhs, const blsSecretKey *rhs) +{ + return mclBnFr_isEqual(&lhs->v, &rhs->v); +} + +int blsPublicKeyIsEqual(const blsPublicKey *lhs, const blsPublicKey *rhs) +{ + return mclBnG2_isEqual(&lhs->v, &rhs->v); +} + +int blsSignatureIsEqual(const blsSignature *lhs, const blsSignature *rhs) +{ + return mclBnG1_isEqual(&lhs->v, &rhs->v); +} + +int blsSecretKeyShare(blsSecretKey *sec, const blsSecretKey* msk, mclSize k, const blsId *id) +{ + return mclBn_FrEvaluatePolynomial(&sec->v, &msk->v, k, &id->v); +} + +int blsPublicKeyShare(blsPublicKey *pub, const blsPublicKey *mpk, mclSize k, const blsId *id) +{ + return mclBn_G2EvaluatePolynomial(&pub->v, &mpk->v, k, &id->v); +} + +int blsSecretKeyRecover(blsSecretKey *sec, const blsSecretKey *secVec, const blsId *idVec, mclSize n) +{ + return mclBn_FrLagrangeInterpolation(&sec->v, &idVec->v, &secVec->v, n); +} + +int blsPublicKeyRecover(blsPublicKey *pub, const blsPublicKey *pubVec, const blsId *idVec, mclSize n) +{ + return mclBn_G2LagrangeInterpolation(&pub->v, &idVec->v, &pubVec->v, n); +} + +int blsSignatureRecover(blsSignature *sig, const blsSignature *sigVec, const blsId *idVec, mclSize n) +{ + return mclBn_G1LagrangeInterpolation(&sig->v, &idVec->v, &sigVec->v, n); +} + +void blsSecretKeyAdd(blsSecretKey *sec, const blsSecretKey *rhs) +{ + mclBnFr_add(&sec->v, &sec->v, &rhs->v); +} + +void blsPublicKeyAdd(blsPublicKey *pub, const blsPublicKey *rhs) +{ + mclBnG2_add(&pub->v, &pub->v, &rhs->v); +} + +void blsSignatureAdd(blsSignature *sig, const blsSignature *rhs) +{ + mclBnG1_add(&sig->v, &sig->v, &rhs->v); +} + +void blsSignatureVerifyOrder(int doVerify) +{ + mclBn_verifyOrderG1(doVerify); +} +void blsPublicKeyVerifyOrder(int doVerify) +{ + mclBn_verifyOrderG2(doVerify); +} +int blsSignatureIsValidOrder(const blsSignature *sig) +{ + return mclBnG1_isValidOrder(&sig->v); +} +int blsPublicKeyIsValidOrder(const blsPublicKey *pub) +{ + return mclBnG2_isValidOrder(&pub->v); +} + +#ifndef BLS_MINIMUM_API +void blsSecretKeySub(blsSecretKey *sec, const blsSecretKey *rhs) +{ + mclBnFr_sub(&sec->v, &sec->v, &rhs->v); +} + +void blsPublicKeySub(blsPublicKey *pub, const blsPublicKey *rhs) +{ + mclBnG2_sub(&pub->v, &pub->v, &rhs->v); +} + +void blsSignatureSub(blsSignature *sig, const blsSignature *rhs) +{ + mclBnG1_sub(&sig->v, &sig->v, &rhs->v); +} +mclSize blsGetOpUnitSize() // FpUint64Size +{ + return Fp::getUnitSize() * sizeof(mcl::fp::Unit) / sizeof(uint64_t); +} + +int blsGetCurveOrder(char *buf, mclSize maxBufSize) +{ + return (int)Fr::getModulo(buf, maxBufSize); +} + +int blsGetFieldOrder(char *buf, mclSize maxBufSize) +{ + return (int)Fp::getModulo(buf, maxBufSize); +} + +int blsGetG1ByteSize() +{ + return mclBn_getG1ByteSize(); +} + +int blsGetFrByteSize() +{ + return mclBn_getFrByteSize(); +} + +void blsGetGeneratorOfG2(blsPublicKey *pub) +{ + *(G2*)pub = getQ(); +} + +int blsIdSetDecStr(blsId *id, const char *buf, mclSize bufSize) +{ + return mclBnFr_setStr(&id->v, buf, bufSize, 10); +} +int blsIdSetHexStr(blsId *id, const char *buf, mclSize bufSize) +{ + return mclBnFr_setStr(&id->v, buf, bufSize, 16); +} + +int blsIdSetLittleEndian(blsId *id, const void *buf, mclSize bufSize) +{ + return mclBnFr_setLittleEndian(&id->v, buf, bufSize); +} + +mclSize blsIdGetDecStr(char *buf, mclSize maxBufSize, const blsId *id) +{ + return mclBnFr_getStr(buf, maxBufSize, &id->v, 10); +} + +mclSize blsIdGetHexStr(char *buf, mclSize maxBufSize, const blsId *id) +{ + return mclBnFr_getStr(buf, maxBufSize, &id->v, 16); +} + +int blsHashToSecretKey(blsSecretKey *sec, const void *buf, mclSize bufSize) +{ + return mclBnFr_setHashOf(&sec->v, buf, bufSize); +} + +#ifndef MCL_DONT_USE_CSPRNG +int blsSecretKeySetByCSPRNG(blsSecretKey *sec) +{ + return mclBnFr_setByCSPRNG(&sec->v); +} +#endif + +void blsGetPop(blsSignature *sig, const blsSecretKey *sec) +{ + blsPublicKey pub; + blsGetPublicKey(&pub, sec); + char buf[1024]; + mclSize n = mclBnG2_serialize(buf, sizeof(buf), &pub.v); + assert(n); + blsSign(sig, sec, buf, n); +} + +int blsVerifyPop(const blsSignature *sig, const blsPublicKey *pub) +{ + char buf[1024]; + mclSize n = mclBnG2_serialize(buf, sizeof(buf), &pub->v); + if (n == 0) return 0; + return blsVerify(sig, pub, buf, n); +} + +mclSize blsIdGetLittleEndian(void *buf, mclSize maxBufSize, const blsId *id) +{ + return mclBnFr_serialize(buf, maxBufSize, &id->v); +} +int blsSecretKeySetDecStr(blsSecretKey *sec, const char *buf, mclSize bufSize) +{ + return mclBnFr_setStr(&sec->v, buf, bufSize, 10); +} +int blsSecretKeySetHexStr(blsSecretKey *sec, const char *buf, mclSize bufSize) +{ + return mclBnFr_setStr(&sec->v, buf, bufSize, 16); +} +mclSize blsSecretKeyGetLittleEndian(void *buf, mclSize maxBufSize, const blsSecretKey *sec) +{ + return mclBnFr_serialize(buf, maxBufSize, &sec->v); +} +mclSize blsSecretKeyGetDecStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec) +{ + return mclBnFr_getStr(buf, maxBufSize, &sec->v, 10); +} +mclSize blsSecretKeyGetHexStr(char *buf, mclSize maxBufSize, const blsSecretKey *sec) +{ + return mclBnFr_getStr(buf, maxBufSize, &sec->v, 16); +} +int blsPublicKeySetHexStr(blsPublicKey *pub, const char *buf, mclSize bufSize) +{ + return mclBnG2_setStr(&pub->v, buf, bufSize, 16); +} +mclSize blsPublicKeyGetHexStr(char *buf, mclSize maxBufSize, const blsPublicKey *pub) +{ + return mclBnG2_getStr(buf, maxBufSize, &pub->v, 16); +} +int blsSignatureSetHexStr(blsSignature *sig, const char *buf, mclSize bufSize) +{ + return mclBnG1_setStr(&sig->v, buf, bufSize, 16); +} +mclSize blsSignatureGetHexStr(char *buf, mclSize maxBufSize, const blsSignature *sig) +{ + return mclBnG1_getStr(buf, maxBufSize, &sig->v, 16); +} +void blsDHKeyExchange(blsPublicKey *out, const blsSecretKey *sec, const blsPublicKey *pub) +{ + mclBnG2_mulCT(&out->v, &pub->v, &sec->v); +} + +#endif + -- cgit v1.2.3