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