aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2018-09-15 21:03:40 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2018-09-15 21:04:11 +0800
commitcfd56e2576f55a5e22804e3612b4004c0d6d9ef3 (patch)
tree7e5e63fa501487886d9f69ca89b51c3ddbf055a5
parentbe54124ccf649ace15ef0f90dbf04f01fab8ac3c (diff)
downloaddexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.tar
dexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.tar.gz
dexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.tar.bz2
dexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.tar.lz
dexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.tar.xz
dexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.tar.zst
dexon-bls-cfd56e2576f55a5e22804e3612b4004c0d6d9ef3.zip
remove duplicated C++ code and libbls.a
-rw-r--r--Makefile40
-rw-r--r--include/bls/bls.hpp369
-rw-r--r--mklib.bat2
-rw-r--r--readme.md9
-rwxr-xr-xsetvar.bat2
-rw-r--r--src/bls.cpp479
-rw-r--r--src/bls_c384.cpp3
-rw-r--r--src/bls_c_impl.hpp (renamed from src/bls_c.cpp)0
8 files changed, 310 insertions, 594 deletions
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 <bls/bls.h>
+#include <stdexcept>
#include <vector>
#include <string>
#include <iosfwd>
#include <stdint.h>
-#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<SecretKey> SecretKeyVec;
typedef std::vector<PublicKey> PublicKeyVec;
@@ -83,25 +89,59 @@ class Id {
blsId self_;
friend class PublicKey;
friend class SecretKey;
- template<class T, class G> friend struct WrapArray;
- impl::Id& getInner() { return *reinterpret_cast<impl::Id*>(this); }
- const impl::Id& getInner() const { return *reinterpret_cast<const impl::Id*>(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<class T, class G> friend struct WrapArray;
- impl::SecretKey& getInner() { return *reinterpret_cast<impl::SecretKey*>(this); }
- const impl::SecretKey& getInner() const { return *reinterpret_cast<const impl::SecretKey*>(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<class T, class G> friend struct WrapArray;
- impl::PublicKey& getInner() { return *reinterpret_cast<impl::PublicKey*>(this); }
- const impl::PublicKey& getInner() const { return *reinterpret_cast<const impl::PublicKey*>(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 <x.a> <x.b> <y.a> <y.b>
+ 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<class T, class G> friend struct WrapArray;
- impl::Signature& getInner() { return *reinterpret_cast<impl::Signature*>(this); }
- const impl::Signature& getInner() const { return *reinterpret_cast<const impl::Signature*>(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 <x> <y>
+ 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 <cybozu/crypto.hpp>
-#include <vector>
-#include <string>
-#define MCLBN_NO_AUTOLINK
-#include <bls/bls.hpp>
-#if MCLBN_FP_UNIT_SIZE == 4
-#include <mcl/bn256.hpp>
-using namespace mcl::bn256;
-#elif MCLBN_FP_UNIT_SIZE == 6
-#include <mcl/bn384.hpp>
-using namespace mcl::bn384;
-#else
- #error "define MCLBN_FP_UNIT_SIZE 4(or 6)"
-#endif
-
-typedef std::vector<Fr> FrVec;
-const std::vector<Fp6> *g_pQcoeff;
-const G2 *g_pQ;
-
-namespace bls {
-
-static const G2& getQ() { return *g_pQ; }
-static const std::vector<Fp6>& getQcoeff() { return *g_pQcoeff; }
-
-static void HashAndMapToG1(G1& P, const std::string& m)
-{
- Fp t;
- t.setHashOf(m);
- mapToG1(P, t);
-}
-
-template<class T, class G, class Vec>
-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<class T, class G>
-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<class G, class V1, class V2>
-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<class T>
-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<Fp6> 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<Fp6> 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<Signature, G1> signW(sigVec, n);
- WrapArray<Id, Fr> 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<PublicKey, G2> 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<PublicKey, G2> pubW(pubVec, n);
- WrapArray<Id, Fr> 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<SecretKey, Fr> 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<SecretKey, Fr> secW(secVec, n);
- WrapArray<Id, Fr> 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_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.cpp b/src/bls_c_impl.hpp
index 75e5a44..75e5a44 100644
--- a/src/bls_c.cpp
+++ b/src/bls_c_impl.hpp