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

     1  #pragma once
     2  /**
     3  	@file
     4  	@brief aggregate signature
     5  	@author MITSUNARI Shigeo(@herumi)
     6  	see http://crypto.stanford.edu/~dabo/papers/aggreg.pdf
     7  	@license modified new BSD license
     8  	http://opensource.org/licenses/BSD-3-Clause
     9  */
    10  #include <cmath>
    11  #include <vector>
    12  #include <iosfwd>
    13  #include <set>
    14  #ifndef MCLBN_FP_UNIT_SIZE
    15  	#define MCLBN_FP_UNIT_SIZE 4
    16  #endif
    17  #if MCLBN_FP_UNIT_SIZE == 4
    18  #include <mcl/bn256.hpp>
    19  namespace mcl {
    20  using namespace mcl::bn256;
    21  }
    22  #elif MCLBN_FP_UNIT_SIZE == 6
    23  #include <mcl/bn384.hpp>
    24  namespace mcl {
    25  using namespace mcl::bn384;
    26  }
    27  #elif MCLBN_FP_UNIT_SIZE == 8
    28  #include <mcl/bn512.hpp>
    29  namespace mcl {
    30  using namespace mcl::bn512;
    31  }
    32  #else
    33  	#error "MCLBN_FP_UNIT_SIZE must be 4, 6, or 8"
    34  #endif
    35  
    36  namespace mcl { namespace aggs {
    37  
    38  /*
    39  	AGGregate Signature Template class
    40  */
    41  template<size_t dummyImpl = 0>
    42  struct AGGST {
    43  	typedef typename G1::BaseFp Fp;
    44  
    45  	class SecretKey;
    46  	class PublicKey;
    47  	class Signature;
    48  
    49  	static G1 P_;
    50  	static G2 Q_;
    51  	static std::vector<Fp6> Qcoeff_;
    52  public:
    53  	static void init(const mcl::CurveParam& cp = mcl::BN254)
    54  	{
    55  		initPairing(cp);
    56  		hashAndMapToG1(P_, "0");
    57  		hashAndMapToG2(Q_, "0");
    58  		precomputeG2(Qcoeff_, Q_);
    59  	}
    60  	class Signature : public fp::Serializable<Signature> {
    61  		G1 S_;
    62  		friend class SecretKey;
    63  		friend class PublicKey;
    64  	public:
    65  		template<class InputStream>
    66  		void load(InputStream& is, int ioMode = IoSerialize)
    67  		{
    68  			S_.load(is, ioMode);
    69  		}
    70  		template<class OutputStream>
    71  		void save(OutputStream& os, int ioMode = IoSerialize) const
    72  		{
    73  			S_.save(os, ioMode);
    74  		}
    75  		friend std::istream& operator>>(std::istream& is, Signature& self)
    76  		{
    77  			self.load(is, fp::detectIoMode(G1::getIoMode(), is));
    78  			return is;
    79  		}
    80  		friend std::ostream& operator<<(std::ostream& os, const Signature& self)
    81  		{
    82  			self.save(os, fp::detectIoMode(G1::getIoMode(), os));
    83  			return os;
    84  		}
    85  		bool operator==(const Signature& rhs) const
    86  		{
    87  			return S_ == rhs.S_;
    88  		}
    89  		bool operator!=(const Signature& rhs) const { return !operator==(rhs); }
    90  		/*
    91  			aggregate sig[0..n) and set *this
    92  		*/
    93  		void aggregate(const Signature *sig, size_t n)
    94  		{
    95  			G1 S;
    96  			S.clear();
    97  			for (size_t i =  0; i < n; i++) {
    98  				S += sig[i].S_;
    99  			}
   100  			S_ = S;
   101  		}
   102  		void aggregate(const std::vector<Signature>& sig)
   103  		{
   104  			aggregate(sig.data(), sig.size());
   105  		}
   106  		/*
   107  			aggregate verification
   108  		*/
   109  		bool verify(const void *const *msgVec, const size_t *sizeVec, const PublicKey *pubVec, size_t n) const
   110  		{
   111  			if (n == 0) return false;
   112  			typedef std::set<Fp> FpSet;
   113  			FpSet msgSet;
   114  			typedef std::vector<G1> G1Vec;
   115  			G1Vec hv(n);
   116  			for (size_t i = 0; i < n; i++) {
   117  				Fp h;
   118  				h.setHashOf(msgVec[i], sizeVec[i]);
   119  				std::pair<typename FpSet::iterator, bool> ret = msgSet.insert(h);
   120  				if (!ret.second) throw cybozu::Exception("aggs::verify:same msg");
   121  				mapToG1(hv[i], h);
   122  			}
   123  			/*
   124  				e(aggSig, xQ) = prod_i e(hv[i], pub[i].Q)
   125  				<=> finalExp(e(-aggSig, xQ) * prod_i millerLoop(hv[i], pub[i].xQ)) == 1
   126  			*/
   127  			GT e1, e2;
   128  			precomputedMillerLoop(e1, -S_, Qcoeff_);
   129  			millerLoop(e2, hv[0], pubVec[0].xQ_);
   130  			for (size_t i = 1; i < n; i++) {
   131  				GT e;
   132  				millerLoop(e, hv[i], pubVec[i].xQ_);
   133  				e2 *= e;
   134  			}
   135  			e1 *= e2;
   136  			finalExp(e1, e1);
   137  			return e1.isOne();
   138  		}
   139  		bool verify(const std::vector<std::string>& msgVec, const std::vector<PublicKey>& pubVec) const
   140  		{
   141  			const size_t n = msgVec.size();
   142  			if (n != pubVec.size()) throw cybozu::Exception("aggs:Signature:verify:bad size") << msgVec.size() << pubVec.size();
   143  			if (n == 0) return false;
   144  			std::vector<const void*> mv(n);
   145  			std::vector<size_t> sv(n);
   146  			for (size_t i = 0; i < n; i++) {
   147  				mv[i] = msgVec[i].c_str();
   148  				sv[i] = msgVec[i].size();
   149  			}
   150  			return verify(&mv[0], &sv[0], &pubVec[0], n);
   151  		}
   152  	};
   153  	class PublicKey : public fp::Serializable<PublicKey> {
   154  		G2 xQ_;
   155  		friend class SecretKey;
   156  		friend class Signature;
   157  	public:
   158  		template<class InputStream>
   159  		void load(InputStream& is, int ioMode = IoSerialize)
   160  		{
   161  			xQ_.load(is, ioMode);
   162  		}
   163  		template<class OutputStream>
   164  		void save(OutputStream& os, int ioMode = IoSerialize) const
   165  		{
   166  			xQ_.save(os, ioMode);
   167  		}
   168  		friend std::istream& operator>>(std::istream& is, PublicKey& self)
   169  		{
   170  			self.load(is, fp::detectIoMode(G2::getIoMode(), is));
   171  			return is;
   172  		}
   173  		friend std::ostream& operator<<(std::ostream& os, const PublicKey& self)
   174  		{
   175  			self.save(os, fp::detectIoMode(G2::getIoMode(), os));
   176  			return os;
   177  		}
   178  		bool operator==(const PublicKey& rhs) const
   179  		{
   180  			return xQ_ == rhs.xQ_;
   181  		}
   182  		bool operator!=(const PublicKey& rhs) const { return !operator==(rhs); }
   183  		bool verify(const Signature& sig, const void *m, size_t mSize) const
   184  		{
   185  			/*
   186  				H = hash(m)
   187  				e(S, Q) = e(H, xQ) where S = xH
   188  				<=> e(S, Q)e(-H, xQ) = 1
   189  				<=> finalExp(millerLoop(S, Q)e(-H, x)) = 1
   190  			*/
   191  			G1 H;
   192  			hashAndMapToG1(H, m,  mSize);
   193  			G1::neg(H, H);
   194  			GT e1, e2;
   195  			precomputedMillerLoop(e1, sig.S_, Qcoeff_);
   196  			millerLoop(e2, H, xQ_);
   197  			e1 *= e2;
   198  			finalExp(e1, e1);
   199  			return e1.isOne();
   200  		}
   201  		bool verify(const Signature& sig, const std::string& m) const
   202  		{
   203  			return verify(sig, m.c_str(), m.size());
   204  		}
   205  	};
   206  	class SecretKey : public fp::Serializable<SecretKey> {
   207  		Fr x_;
   208  		friend class PublicKey;
   209  		friend class Signature;
   210  	public:
   211  		template<class InputStream>
   212  		void load(InputStream& is, int ioMode = IoSerialize)
   213  		{
   214  			x_.load(is, ioMode);
   215  		}
   216  		template<class OutputStream>
   217  		void save(OutputStream& os, int ioMode = IoSerialize) const
   218  		{
   219  			x_.save(os, ioMode);
   220  		}
   221  		friend std::istream& operator>>(std::istream& is, SecretKey& self)
   222  		{
   223  			self.load(is, fp::detectIoMode(Fr::getIoMode(), is));
   224  			return is;
   225  		}
   226  		friend std::ostream& operator<<(std::ostream& os, const SecretKey& self)
   227  		{
   228  			self.save(os, fp::detectIoMode(Fr::getIoMode(), os));
   229  			return os;
   230  		}
   231  		bool operator==(const SecretKey& rhs) const
   232  		{
   233  			return x_ == rhs.x_;
   234  		}
   235  		bool operator!=(const SecretKey& rhs) const { return !operator==(rhs); }
   236  		void init()
   237  		{
   238  			x_.setByCSPRNG();
   239  		}
   240  		void getPublicKey(PublicKey& pub) const
   241  		{
   242  			G2::mul(pub.xQ_, Q_, x_);
   243  		}
   244  		void sign(Signature& sig, const void *m, size_t mSize) const
   245  		{
   246  			hashAndMapToG1(sig.S_, m, mSize);
   247  			G1::mul(sig.S_, sig.S_, x_);
   248  		}
   249  		void sign(Signature& sig, const std::string& m) const
   250  		{
   251  			sign(sig, m.c_str(), m.size());
   252  		}
   253  	};
   254  };
   255  
   256  template<size_t dummyImpl> G1 AGGST<dummyImpl>::P_;
   257  template<size_t dummyImpl> G2 AGGST<dummyImpl>::Q_;
   258  template<size_t dummyImpl> std::vector<Fp6> AGGST<dummyImpl>::Qcoeff_;
   259  
   260  typedef AGGST<> AGGS;
   261  typedef AGGS::SecretKey SecretKey;
   262  typedef AGGS::PublicKey PublicKey;
   263  typedef AGGS::Signature Signature;
   264  
   265  } } // mcl::aggs