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