github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/bls/bls.hpp (about)

     1  #pragma once
     2  /**
     3  	@file
     4  	@brief BLS threshold signature on BN curve
     5  	@author MITSUNARI Shigeo(@herumi)
     6  	@license modified new BSD license
     7  	http://opensource.org/licenses/BSD-3-Clause
     8  */
     9  #include <bls/bls.h>
    10  #include <stdexcept>
    11  #include <vector>
    12  #include <string>
    13  #include <iosfwd>
    14  #include <stdint.h>
    15  
    16  namespace bls {
    17  
    18  // same value with IoMode of mcl/op.hpp
    19  enum {
    20  	IoBin = 2, // binary number
    21  	IoDec = 10, // decimal number
    22  	IoHex = 16, // hexadecimal number
    23  	IoPrefix = 128, // append '0b'(bin) or '0x'(hex)
    24  	IoSerialize = 512,
    25  	IoFixedByteSeq = IoSerialize // fixed byte representation
    26  };
    27  
    28  /*
    29  	BLS signature
    30  	e : G2 x G1 -> Fp12
    31  	Q in G2 ; fixed global parameter
    32  	H : {str} -> G1
    33  	s : secret key
    34  	sQ ; public key
    35  	s H(m) ; signature of m
    36  	verify ; e(sQ, H(m)) = e(Q, s H(m))
    37  */
    38  
    39  /*
    40  	initialize this library
    41  	call this once before using the other method
    42  	@param curve [in] type of curve
    43  	@param compiledTimevar [in] use the default value
    44  	@note init() is not thread safe
    45  */
    46  inline void init(int curve = mclBn_CurveFp254BNb, int compiledTimeVar = MCLBN_COMPILED_TIME_VAR)
    47  {
    48  	if (blsInit(curve, compiledTimeVar) != 0) throw std::invalid_argument("blsInit");
    49  }
    50  inline size_t getOpUnitSize() { return blsGetOpUnitSize(); }
    51  
    52  inline void getCurveOrder(std::string& str)
    53  {
    54  	str.resize(1024);
    55  	mclSize n = blsGetCurveOrder(&str[0], str.size());
    56  	if (n == 0) throw std::runtime_error("blsGetCurveOrder");
    57  	str.resize(n);
    58  }
    59  inline void getFieldOrder(std::string& str)
    60  {
    61  	str.resize(1024);
    62  	mclSize n = blsGetFieldOrder(&str[0], str.size());
    63  	if (n == 0) throw std::runtime_error("blsGetFieldOrder");
    64  	str.resize(n);
    65  }
    66  inline int getG1ByteSize() { return blsGetG1ByteSize(); }
    67  inline int getFrByteSize() { return blsGetFrByteSize(); }
    68  
    69  namespace local {
    70  /*
    71  	the value of secretKey and Id must be less than
    72  	r = 0x2523648240000001ba344d8000000007ff9f800000000010a10000000000000d
    73  	sizeof(uint64_t) * keySize byte
    74  */
    75  const size_t keySize = MCLBN_FP_UNIT_SIZE;
    76  }
    77  
    78  class SecretKey;
    79  class PublicKey;
    80  class Signature;
    81  class Id;
    82  
    83  typedef std::vector<SecretKey> SecretKeyVec;
    84  typedef std::vector<PublicKey> PublicKeyVec;
    85  typedef std::vector<Signature> SignatureVec;
    86  typedef std::vector<Id> IdVec;
    87  
    88  class Id {
    89  	blsId self_;
    90  	friend class PublicKey;
    91  	friend class SecretKey;
    92  	friend class Signature;
    93  public:
    94  	Id(unsigned int id = 0)
    95  	{
    96  		blsIdSetInt(&self_, id);
    97  	}
    98  	bool operator==(const Id& rhs) const
    99  	{
   100  		return blsIdIsEqual(&self_, &rhs.self_) == 1;
   101  	}
   102  	bool operator!=(const Id& rhs) const { return !(*this == rhs); }
   103  	friend std::ostream& operator<<(std::ostream& os, const Id& id)
   104  	{
   105  		std::string str;
   106  		id.getStr(str, 16|IoPrefix);
   107  		return os << str;
   108  	}
   109  	friend std::istream& operator>>(std::istream& is, Id& id)
   110  	{
   111  		std::string str;
   112  		is >> str;
   113  		id.setStr(str, 16);
   114  		return is;
   115  	}
   116  	void getStr(std::string& str, int ioMode = 0) const
   117  	{
   118  		str.resize(1024);
   119  		size_t n = mclBnFr_getStr(&str[0], str.size(), &self_.v, ioMode);
   120  		if (n == 0) throw std::runtime_error("mclBnFr_getStr");
   121  		str.resize(n);
   122  	}
   123  	void setStr(const std::string& str, int ioMode = 0)
   124  	{
   125  		int ret = mclBnFr_setStr(&self_.v, str.c_str(), str.size(), ioMode);
   126  		if (ret != 0) throw std::runtime_error("mclBnFr_setStr");
   127  	}
   128  	bool isZero() const
   129  	{
   130  		return mclBnFr_isZero(&self_.v) == 1;
   131  	}
   132  	/*
   133  		set p[0, .., keySize)
   134  		@note the value must be less than r
   135  	*/
   136  	void set(const uint64_t *p)
   137  	{
   138  		setLittleEndian(p, local::keySize * sizeof(uint64_t));
   139  	}
   140  	// bufSize is truncted/zero extended to keySize
   141  	void setLittleEndian(const void *buf, size_t bufSize)
   142  	{
   143  		mclBnFr_setLittleEndian(&self_.v, buf, bufSize);
   144  	}
   145  };
   146  
   147  /*
   148  	s ; secret key
   149  */
   150  class SecretKey {
   151  	blsSecretKey self_;
   152  public:
   153  	bool operator==(const SecretKey& rhs) const
   154  	{
   155  		return blsSecretKeyIsEqual(&self_, &rhs.self_) == 1;
   156  	}
   157  	bool operator!=(const SecretKey& rhs) const { return !(*this == rhs); }
   158  	friend std::ostream& operator<<(std::ostream& os, const SecretKey& sec)
   159  	{
   160  		std::string str;
   161  		sec.getStr(str, 16|IoPrefix);
   162  		return os << str;
   163  	}
   164  	friend std::istream& operator>>(std::istream& is, SecretKey& sec)
   165  	{
   166  		std::string str;
   167  		is >> str;
   168  		sec.setStr(str);
   169  		return is;
   170  	}
   171  	void getStr(std::string& str, int ioMode = 0) const
   172  	{
   173  		str.resize(1024);
   174  		size_t n = mclBnFr_getStr(&str[0], str.size(), &self_.v, ioMode);
   175  		if (n == 0) throw std::runtime_error("mclBnFr_getStr");
   176  		str.resize(n);
   177  	}
   178  	void setStr(const std::string& str, int ioMode = 0)
   179  	{
   180  		int ret = mclBnFr_setStr(&self_.v, str.c_str(), str.size(), ioMode);
   181  		if (ret != 0) throw std::runtime_error("mclBnFr_setStr");
   182  	}
   183  	/*
   184  		initialize secretKey with random number
   185  	*/
   186  	void init()
   187  	{
   188  		int ret = blsSecretKeySetByCSPRNG(&self_);
   189  		if (ret != 0) throw std::runtime_error("blsSecretKeySetByCSPRNG");
   190  	}
   191  	/*
   192  		set secretKey with p[0, .., keySize) and set id = 0
   193  		@note the value must be less than r
   194  	*/
   195  	void set(const uint64_t *p)
   196  	{
   197  		setLittleEndian(p, local::keySize * sizeof(uint64_t));
   198  	}
   199  	// bufSize is truncted/zero extended to keySize
   200  	void setLittleEndian(const void *buf, size_t bufSize)
   201  	{
   202  		mclBnFr_setLittleEndian(&self_.v, buf, bufSize);
   203  	}
   204  	// set hash of buf
   205  	void setHashOf(const void *buf, size_t bufSize)
   206  	{
   207  		int ret = mclBnFr_setHashOf(&self_.v, buf, bufSize);
   208  		if (ret != 0) throw std::runtime_error("mclBnFr_setHashOf");
   209  	}
   210  	void getPublicKey(PublicKey& pub) const;
   211  	// constant time sign
   212  	// sign hash(m)
   213  	void sign(Signature& sig, const void *m, size_t size) const;
   214  	void sign(Signature& sig, const std::string& m) const
   215  	{
   216  		sign(sig, m.c_str(), m.size());
   217  	}
   218  	// sign hashed value
   219  	void signHash(Signature& sig, const void *h, size_t size) const;
   220  	void signHash(Signature& sig, const std::string& h) const
   221  	{
   222  		signHash(sig, h.c_str(), h.size());
   223  	}
   224  	/*
   225  		make Pop(Proof of Possesion)
   226  		pop = prv.sign(pub)
   227  	*/
   228  	void getPop(Signature& pop) const;
   229  	/*
   230  		make [s_0, ..., s_{k-1}] to prepare k-out-of-n secret sharing
   231  	*/
   232  	void getMasterSecretKey(SecretKeyVec& msk, size_t k) const
   233  	{
   234  		if (k <= 1) throw std::invalid_argument("getMasterSecretKey");
   235  		msk.resize(k);
   236  		msk[0] = *this;
   237  		for (size_t i = 1; i < k; i++) {
   238  			msk[i].init();
   239  		}
   240  	}
   241  	/*
   242  		set a secret key for id > 0 from msk
   243  	*/
   244  	void set(const SecretKeyVec& msk, const Id& id)
   245  	{
   246  		set(msk.data(), msk.size(), id);
   247  	}
   248  	/*
   249  		recover secretKey from k secVec
   250  	*/
   251  	void recover(const SecretKeyVec& secVec, const IdVec& idVec)
   252  	{
   253  		if (secVec.size() != idVec.size()) throw std::invalid_argument("SecretKey:recover");
   254  		recover(secVec.data(), idVec.data(), idVec.size());
   255  	}
   256  	/*
   257  		add secret key
   258  	*/
   259  	void add(const SecretKey& rhs);
   260  
   261  	// the following methods are for C api
   262  	/*
   263  		the size of msk must be k
   264  	*/
   265  	void set(const SecretKey *msk, size_t k, const Id& id)
   266  	{
   267  		int ret = blsSecretKeyShare(&self_, &msk->self_, k, &id.self_);
   268  		if (ret != 0) throw std::runtime_error("blsSecretKeyShare");
   269  	}
   270  	void recover(const SecretKey *secVec, const Id *idVec, size_t n)
   271  	{
   272  		int ret = blsSecretKeyRecover(&self_, &secVec->self_, &idVec->self_, n);
   273  		if (ret != 0) throw std::runtime_error("blsSecretKeyRecover:same id");
   274  	}
   275  };
   276  
   277  /*
   278  	sQ ; public key
   279  */
   280  class PublicKey {
   281  	blsPublicKey self_;
   282  	friend class SecretKey;
   283  	friend class Signature;
   284  public:
   285  	bool operator==(const PublicKey& rhs) const
   286  	{
   287  		return blsPublicKeyIsEqual(&self_, &rhs.self_) == 1;
   288  	}
   289  	bool operator!=(const PublicKey& rhs) const { return !(*this == rhs); }
   290  	friend std::ostream& operator<<(std::ostream& os, const PublicKey& pub)
   291  	{
   292  		std::string str;
   293  		pub.getStr(str, 16|IoPrefix);
   294  		return os << str;
   295  	}
   296  	friend std::istream& operator>>(std::istream& is, PublicKey& pub)
   297  	{
   298  		std::string str;
   299  		is >> str;
   300  		if (str != "0") {
   301  			// 1 <x.a> <x.b> <y.a> <y.b>
   302  			std::string t;
   303  #ifdef BLS_SWAP_G
   304  			const int elemNum = 2;
   305  #else
   306  			const int elemNum = 4;
   307  #endif
   308  			for (int i = 0; i < elemNum; i++) {
   309  				is >> t;
   310  				str += ' ';
   311  				str += t;
   312  			}
   313  		}
   314  		pub.setStr(str, 16);
   315  		return is;
   316  	}
   317  	void getStr(std::string& str, int ioMode = 0) const
   318  	{
   319  		str.resize(1024);
   320  #ifdef BLS_SWAP_G
   321  		size_t n = mclBnG1_getStr(&str[0], str.size(), &self_.v, ioMode);
   322  #else
   323  		size_t n = mclBnG2_getStr(&str[0], str.size(), &self_.v, ioMode);
   324  #endif
   325  		if (n == 0) throw std::runtime_error("PublicKey:getStr");
   326  		str.resize(n);
   327  	}
   328  	void setStr(const std::string& str, int ioMode = 0)
   329  	{
   330  #ifdef BLS_SWAP_G
   331  		int ret = mclBnG1_setStr(&self_.v, str.c_str(), str.size(), ioMode);
   332  #else
   333  		int ret = mclBnG2_setStr(&self_.v, str.c_str(), str.size(), ioMode);
   334  #endif
   335  		if (ret != 0) throw std::runtime_error("PublicKey:setStr");
   336  	}
   337  	/*
   338  		set public for id from mpk
   339  	*/
   340  	void set(const PublicKeyVec& mpk, const Id& id)
   341  	{
   342  		set(mpk.data(), mpk.size(), id);
   343  	}
   344  	/*
   345  		recover publicKey from k pubVec
   346  	*/
   347  	void recover(const PublicKeyVec& pubVec, const IdVec& idVec)
   348  	{
   349  		if (pubVec.size() != idVec.size()) throw std::invalid_argument("PublicKey:recover");
   350  		recover(pubVec.data(), idVec.data(), idVec.size());
   351  	}
   352  	/*
   353  		add public key
   354  	*/
   355  	void add(const PublicKey& rhs)
   356  	{
   357  		blsPublicKeyAdd(&self_, &rhs.self_);
   358  	}
   359  
   360  	// the following methods are for C api
   361  	void set(const PublicKey *mpk, size_t k, const Id& id)
   362  	{
   363  		int ret = blsPublicKeyShare(&self_, &mpk->self_, k, &id.self_);
   364  		if (ret != 0) throw std::runtime_error("blsPublicKeyShare");
   365  	}
   366  	void recover(const PublicKey *pubVec, const Id *idVec, size_t n)
   367  	{
   368  		int ret = blsPublicKeyRecover(&self_, &pubVec->self_, &idVec->self_, n);
   369  		if (ret != 0) throw std::runtime_error("blsPublicKeyRecover");
   370  	}
   371  };
   372  
   373  /*
   374  	s H(m) ; signature
   375  */
   376  class Signature {
   377  	blsSignature self_;
   378  	friend class SecretKey;
   379  public:
   380  	bool operator==(const Signature& rhs) const
   381  	{
   382  		return blsSignatureIsEqual(&self_, &rhs.self_) == 1;
   383  	}
   384  	bool operator!=(const Signature& rhs) const { return !(*this == rhs); }
   385  	friend std::ostream& operator<<(std::ostream& os, const Signature& sig)
   386  	{
   387  		std::string str;
   388  		sig.getStr(str, 16|IoPrefix);
   389  		return os << str;
   390  	}
   391  	friend std::istream& operator>>(std::istream& is, Signature& sig)
   392  	{
   393  		std::string str;
   394  		is >> str;
   395  		if (str != "0") {
   396  			// 1 <x> <y>
   397  			std::string t;
   398  #ifdef BLS_SWAP_G
   399  			const int elemNum = 4;
   400  #else
   401  			const int elemNum = 2;
   402  #endif
   403  			for (int i = 0; i < elemNum; i++) {
   404  				is >> t;
   405  				str += ' ';
   406  				str += t;
   407  			}
   408  		}
   409  		sig.setStr(str, 16);
   410  		return is;
   411  	}
   412  	void getStr(std::string& str, int ioMode = 0) const
   413  	{
   414  		str.resize(1024);
   415  #ifdef BLS_SWAP_G
   416  		size_t n = mclBnG2_getStr(&str[0], str.size(), &self_.v, ioMode);
   417  #else
   418  		size_t n = mclBnG1_getStr(&str[0], str.size(), &self_.v, ioMode);
   419  #endif
   420  		if (n == 0) throw std::runtime_error("Signature:tgetStr");
   421  		str.resize(n);
   422  	}
   423  	void setStr(const std::string& str, int ioMode = 0)
   424  	{
   425  #ifdef BLS_SWAP_G
   426  		int ret = mclBnG2_setStr(&self_.v, str.c_str(), str.size(), ioMode);
   427  #else
   428  		int ret = mclBnG1_setStr(&self_.v, str.c_str(), str.size(), ioMode);
   429  #endif
   430  		if (ret != 0) throw std::runtime_error("Signature:setStr");
   431  	}
   432  	bool verify(const PublicKey& pub, const void *m, size_t size) const
   433  	{
   434  		return blsVerify(&self_, &pub.self_, m, size) == 1;
   435  	}
   436  	bool verify(const PublicKey& pub, const std::string& m) const
   437  	{
   438  		return verify(pub, m.c_str(), m.size());
   439  	}
   440  	bool verifyHash(const PublicKey& pub, const void *h, size_t size) const
   441  	{
   442  		return blsVerifyHash(&self_, &pub.self_, h, size) == 1;
   443  	}
   444  	bool verifyHash(const PublicKey& pub, const std::string& h) const
   445  	{
   446  		return verifyHash(pub, h.c_str(), h.size());
   447  	}
   448  	bool verifyAggregatedHashes(const PublicKey *pubVec, const void *hVec, size_t sizeofHash, size_t n) const
   449  	{
   450  		return blsVerifyAggregatedHashes(&self_, &pubVec[0].self_, hVec, sizeofHash, n) == 1;
   451  	}
   452  	/*
   453  		verify self(pop) with pub
   454  	*/
   455  	bool verify(const PublicKey& pub) const
   456  	{
   457  		std::string str;
   458  		pub.getStr(str);
   459  		return verify(pub, str);
   460  	}
   461  	/*
   462  		recover sig from k sigVec
   463  	*/
   464  	void recover(const SignatureVec& sigVec, const IdVec& idVec)
   465  	{
   466  		if (sigVec.size() != idVec.size()) throw std::invalid_argument("Signature:recover");
   467  		recover(sigVec.data(), idVec.data(), idVec.size());
   468  	}
   469  	/*
   470  		add signature
   471  	*/
   472  	void add(const Signature& rhs)
   473  	{
   474  		blsSignatureAdd(&self_, &rhs.self_);
   475  	}
   476  
   477  	// the following methods are for C api
   478  	void recover(const Signature* sigVec, const Id *idVec, size_t n)
   479  	{
   480  		int ret = blsSignatureRecover(&self_, &sigVec->self_, &idVec->self_, n);
   481  		if (ret != 0) throw std::runtime_error("blsSignatureRecover:same id");
   482  	}
   483  };
   484  
   485  /*
   486  	make master public key [s_0 Q, ..., s_{k-1} Q] from msk
   487  */
   488  inline void getMasterPublicKey(PublicKeyVec& mpk, const SecretKeyVec& msk)
   489  {
   490  	const size_t n = msk.size();
   491  	mpk.resize(n);
   492  	for (size_t i = 0; i < n; i++) {
   493  		msk[i].getPublicKey(mpk[i]);
   494  	}
   495  }
   496  
   497  inline void SecretKey::getPublicKey(PublicKey& pub) const
   498  {
   499  	blsGetPublicKey(&pub.self_, &self_);
   500  }
   501  inline void SecretKey::sign(Signature& sig, const void *m, size_t size) const
   502  {
   503  	blsSign(&sig.self_, &self_, m, size);
   504  }
   505  inline void SecretKey::signHash(Signature& sig, const void *h, size_t size) const
   506  {
   507  	if (blsSignHash(&sig.self_, &self_, h, size) != 0) throw std::runtime_error("bad h");
   508  }
   509  inline void SecretKey::getPop(Signature& pop) const
   510  {
   511  	PublicKey pub;
   512  	getPublicKey(pub);
   513  	std::string m;
   514  	pub.getStr(m);
   515  	sign(pop, m);
   516  }
   517  
   518  /*
   519  	make pop from msk and mpk
   520  */
   521  inline void getPopVec(SignatureVec& popVec, const SecretKeyVec& msk)
   522  {
   523  	const size_t n = msk.size();
   524  	popVec.resize(n);
   525  	for (size_t i = 0; i < n; i++) {
   526  		msk[i].getPop(popVec[i]);
   527  	}
   528  }
   529  
   530  inline Signature operator+(const Signature& a, const Signature& b) { Signature r(a); r.add(b); return r; }
   531  inline PublicKey operator+(const PublicKey& a, const PublicKey& b) { PublicKey r(a); r.add(b); return r; }
   532  inline SecretKey operator+(const SecretKey& a, const SecretKey& b) { SecretKey r(a); r.add(b); return r; }
   533  
   534  } //bls