Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

bls_worker.h
Go to the documentation of this file.
1 // Copyright (c) 2018-2020 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef DASH_CRYPTO_BLS_WORKER_H
6 #define DASH_CRYPTO_BLS_WORKER_H
7 
8 #include <bls/bls.h>
9 
10 #include <ctpl.h>
11 
12 #include <future>
13 #include <mutex>
14 
15 #include <boost/lockfree/queue.hpp>
16 
17 // Low level BLS/DKG stuff. All very compute intensive and optimized for parallelization
18 // The worker tries to parallelize as much as possible and utilizes a few properties of BLS aggregation to speed up things
19 // For example, public key vectors can be aggregated in parallel if they are split into batches and the batched aggregations are
20 // aggregated to a final public key. This utilizes that when aggregating keys (a+b+c+d) gives the same result as (a+b)+(c+d)
22 {
23 public:
24  typedef std::function<void(const CBLSSignature&)> SignDoneCallback;
25  typedef std::function<void(bool)> SigVerifyDoneCallback;
26  typedef std::function<bool()> CancelCond;
27 
28 private:
30 
31  static const int SIG_VERIFY_BATCH_SIZE = 8;
32  struct SigVerifyJob {
38  SigVerifyJob(SigVerifyDoneCallback&& _doneCallback, CancelCond&& _cancelCond, const CBLSSignature& _sig, const CBLSPublicKey& _pubKey, const uint256& _msgHash) :
39  doneCallback(_doneCallback),
40  cancelCond(_cancelCond),
41  sig(_sig),
42  pubKey(_pubKey),
43  msgHash(_msgHash)
44  {
45  }
46  };
47 
48  std::mutex sigVerifyMutex;
50  std::vector<SigVerifyJob> sigVerifyQueue;
51 
52 public:
53  CBLSWorker();
54  ~CBLSWorker();
55 
56  void Start();
57  void Stop();
58 
59  bool GenerateContributions(int threshold, const BLSIdVector& ids, BLSVerificationVectorPtr& vvecRet, BLSSecretKeyVector& skShares);
60 
61  // The following functions are all used to aggregate verification (public key) vectors
62  // Inputs are in the following form:
63  // [
64  // [a1, b1, c1, d1],
65  // [a2, b2, c2, d2],
66  // [a3, b3, c3, d3],
67  // [a4, b4, c4, d4],
68  // ]
69  // The result is in the following form:
70  // [ a1+a2+a3+a4, b1+b2+b3+b4, c1+c2+c3+c4, d1+d2+d3+d4]
71  // Multiple things can be parallelized here. For example, all 4 entries in the result vector can be calculated in parallel
72  // Also, each individual vector can be split into multiple batches and aggregating the batches can also be paralellized.
73  void AsyncBuildQuorumVerificationVector(const std::vector<BLSVerificationVectorPtr>& vvecs,
74  size_t start, size_t count, bool parallel,
75  std::function<void(const BLSVerificationVectorPtr&)> doneCallback);
76  std::future<BLSVerificationVectorPtr> AsyncBuildQuorumVerificationVector(const std::vector<BLSVerificationVectorPtr>& vvecs,
77  size_t start, size_t count, bool parallel);
78  BLSVerificationVectorPtr BuildQuorumVerificationVector(const std::vector<BLSVerificationVectorPtr>& vvecs,
79  size_t start = 0, size_t count = 0, bool parallel = true);
80 
81  // The following functions are all used to aggregate single vectors
82  // Inputs are in the following form:
83  // [a, b, c, d],
84  // The result is simply a+b+c+d
85  // Aggregation is paralellized by splitting up the input vector into multiple batches and then aggregating the individual batch results
86  void AsyncAggregateSecretKeys(const BLSSecretKeyVector& secKeys,
87  size_t start, size_t count, bool parallel,
88  std::function<void(const CBLSSecretKey&)> doneCallback);
89  std::future<CBLSSecretKey> AsyncAggregateSecretKeys(const BLSSecretKeyVector& secKeys,
90  size_t start, size_t count, bool parallel);
91  CBLSSecretKey AggregateSecretKeys(const BLSSecretKeyVector& secKeys, size_t start = 0, size_t count = 0, bool parallel = true);
92 
93  void AsyncAggregatePublicKeys(const BLSPublicKeyVector& pubKeys,
94  size_t start, size_t count, bool parallel,
95  std::function<void(const CBLSPublicKey&)> doneCallback);
96  std::future<CBLSPublicKey> AsyncAggregatePublicKeys(const BLSPublicKeyVector& pubKeys,
97  size_t start, size_t count, bool parallel);
98  CBLSPublicKey AggregatePublicKeys(const BLSPublicKeyVector& pubKeys, size_t start = 0, size_t count = 0, bool parallel = true);
99 
100  void AsyncAggregateSigs(const BLSSignatureVector& sigs,
101  size_t start, size_t count, bool parallel,
102  std::function<void(const CBLSSignature&)> doneCallback);
103  std::future<CBLSSignature> AsyncAggregateSigs(const BLSSignatureVector& sigs,
104  size_t start, size_t count, bool parallel);
105  CBLSSignature AggregateSigs(const BLSSignatureVector& sigs, size_t start = 0, size_t count = 0, bool parallel = true);
106 
107 
108  // Calculate public key share from public key vector and id. Not parallelized
110 
111  // The following functions verify multiple verification vectors and contributions for the same id
112  // This is parallelized by performing batched verification. The verification vectors and the contributions of
113  // a batch are aggregated (in parallel, see AsyncBuildQuorumVerificationVector and AsyncBuildSecretKeyShare). The
114  // result per batch is a single aggregated verification vector and a single aggregated contribution, which are then
115  // verified with VerifyContributionShare. If verification of the aggregated inputs is successful, the whole batch
116  // is marked as valid. If the batch verification fails, the individual entries are verified in a non-aggregated manner
117  void AsyncVerifyContributionShares(const CBLSId& forId, const std::vector<BLSVerificationVectorPtr>& vvecs, const BLSSecretKeyVector& skShares,
118  bool parallel, bool aggregated, std::function<void(const std::vector<bool>&)> doneCallback);
119  std::future<std::vector<bool> > AsyncVerifyContributionShares(const CBLSId& forId, const std::vector<BLSVerificationVectorPtr>& vvecs, const BLSSecretKeyVector& skShares,
120  bool parallel, bool aggregated);
121  std::vector<bool> VerifyContributionShares(const CBLSId& forId, const std::vector<BLSVerificationVectorPtr>& vvecs, const BLSSecretKeyVector& skShares,
122  bool parallel = true, bool aggregated = true);
123 
124  std::future<bool> AsyncVerifyContributionShare(const CBLSId& forId, const BLSVerificationVectorPtr& vvec, const CBLSSecretKey& skContribution);
125 
126  // Non paralellized verification of a single contribution
127  bool VerifyContributionShare(const CBLSId& forId, const BLSVerificationVectorPtr& vvec, const CBLSSecretKey& skContribution);
128 
129  // Simple verification of vectors. Checks x.IsValid() for every entry and checks for duplicate entries
130  bool VerifyVerificationVector(const BLSVerificationVector& vvec, size_t start = 0, size_t count = 0);
131  bool VerifyVerificationVectors(const std::vector<BLSVerificationVectorPtr>& vvecs, size_t start = 0, size_t count = 0);
132  bool VerifySecretKeyVector(const BLSSecretKeyVector& secKeys, size_t start = 0, size_t count = 0);
133  bool VerifySignatureVector(const BLSSignatureVector& sigs, size_t start = 0, size_t count = 0);
134 
135  // Internally batched signature signing and verification
136  void AsyncSign(const CBLSSecretKey& secKey, const uint256& msgHash, SignDoneCallback doneCallback);
137  std::future<CBLSSignature> AsyncSign(const CBLSSecretKey& secKey, const uint256& msgHash);
138  void AsyncVerifySig(const CBLSSignature& sig, const CBLSPublicKey& pubKey, const uint256& msgHash, SigVerifyDoneCallback doneCallback, CancelCond cancelCond = [] { return false; });
139  std::future<bool> AsyncVerifySig(const CBLSSignature& sig, const CBLSPublicKey& pubKey, const uint256& msgHash, CancelCond cancelCond = [] { return false; });
141 
142 private:
143  void PushSigVerifyBatch();
144 };
145 
146 // Builds and caches different things from CBLSWorker
147 // Cache keys are provided externally as computing hashes on BLS vectors is too expensive
148 // If multiple threads try to build the same thing at the same time, only one will actually build it
149 // and the other ones will wait for the result of the first caller
151 {
152 private:
154 
155  std::mutex cacheCs;
156  std::map<uint256, std::shared_future<BLSVerificationVectorPtr> > vvecCache;
157  std::map<uint256, std::shared_future<CBLSSecretKey> > secretKeyShareCache;
158  std::map<uint256, std::shared_future<CBLSPublicKey> > publicKeyShareCache;
159 
160 public:
161  explicit CBLSWorkerCache(CBLSWorker& _worker) :
162  worker(_worker) {}
163 
164  BLSVerificationVectorPtr BuildQuorumVerificationVector(const uint256& cacheKey, const std::vector<BLSVerificationVectorPtr>& vvecs)
165  {
166  return GetOrBuild(cacheKey, vvecCache, [&]() {
168  });
169  }
171  {
172  return GetOrBuild(cacheKey, secretKeyShareCache, [&]() {
173  return worker.AggregateSecretKeys(skShares);
174  });
175  }
176  CBLSPublicKey BuildPubKeyShare(const uint256& cacheKey, const BLSVerificationVectorPtr& vvec, const CBLSId& id)
177  {
178  return GetOrBuild(cacheKey, publicKeyShareCache, [&]() {
179  return worker.BuildPubKeyShare(vvec, id);
180  });
181  }
182 
183 private:
184  template <typename T, typename Builder>
185  T GetOrBuild(const uint256& cacheKey, std::map<uint256, std::shared_future<T> >& cache, Builder&& builder)
186  {
187  cacheCs.lock();
188  auto it = cache.find(cacheKey);
189  if (it != cache.end()) {
190  auto f = it->second;
191  cacheCs.unlock();
192  return f.get();
193  }
194 
195  std::promise<T> p;
196  cache.emplace(cacheKey, p.get_future());
197  cacheCs.unlock();
198 
199  T v = builder();
200  p.set_value(v);
201  return v;
202  }
203 };
204 
205 #endif //DASH_CRYPTO_BLS_WORKER_H
bool VerifyContributionShare(const CBLSId &forId, const BLSVerificationVectorPtr &vvec, const CBLSSecretKey &skContribution)
Definition: bls_worker.cpp:776
std::mutex cacheCs
Definition: bls_worker.h:155
int sigVerifyBatchesInProgress
Definition: bls_worker.h:49
std::vector< CBLSPublicKey > BLSPublicKeyVector
Definition: bls.h:466
CBLSPublicKey pubKey
Definition: bls_worker.h:36
T GetOrBuild(const uint256 &cacheKey, std::map< uint256, std::shared_future< T > > &cache, Builder &&builder)
Definition: bls_worker.h:185
std::map< uint256, std::shared_future< CBLSSecretKey > > secretKeyShareCache
Definition: bls_worker.h:157
void AsyncBuildQuorumVerificationVector(const std::vector< BLSVerificationVectorPtr > &vvecs, size_t start, size_t count, bool parallel, std::function< void(const BLSVerificationVectorPtr &)> doneCallback)
Definition: bls_worker.cpp:600
bool VerifySecretKeyVector(const BLSSecretKeyVector &secKeys, size_t start=0, size_t count=0)
Definition: bls_worker.cpp:823
SigVerifyDoneCallback doneCallback
Definition: bls_worker.h:33
void AsyncVerifyContributionShares(const CBLSId &forId, const std::vector< BLSVerificationVectorPtr > &vvecs, const BLSSecretKeyVector &skShares, bool parallel, bool aggregated, std::function< void(const std::vector< bool > &)> doneCallback)
Definition: bls_worker.cpp:726
std::function< void(bool)> SigVerifyDoneCallback
Definition: bls_worker.h:25
static const int SIG_VERIFY_BATCH_SIZE
Definition: bls_worker.h:31
CBLSPublicKey AggregatePublicKeys(const BLSPublicKeyVector &pubKeys, size_t start=0, size_t count=0, bool parallel=true)
Definition: bls_worker.cpp:691
std::vector< CBLSPublicKey > BLSVerificationVector
Definition: bls.h:465
std::mutex sigVerifyMutex
Definition: bls_worker.h:48
BLSVerificationVectorPtr BuildQuorumVerificationVector(const std::vector< BLSVerificationVectorPtr > &vvecs, size_t start=0, size_t count=0, bool parallel=true)
Definition: bls_worker.cpp:628
std::vector< CBLSSecretKey > BLSSecretKeyVector
Definition: bls.h:467
bool VerifyVerificationVector(const BLSVerificationVector &vvec, size_t start=0, size_t count=0)
Definition: bls_worker.cpp:788
bool GenerateContributions(int threshold, const BLSIdVector &ids, BLSVerificationVectorPtr &vvecRet, BLSSecretKeyVector &skShares)
Definition: bls_worker.cpp:75
CBLSSecretKey AggregateSecretKeys(const uint256 &cacheKey, const BLSSecretKeyVector &skShares)
Definition: bls_worker.h:170
std::vector< CBLSSignature > BLSSignatureVector
Definition: bls.h:468
ctpl::thread_pool workerPool
Definition: bls_worker.h:29
Definition: bls.h:218
SigVerifyJob(SigVerifyDoneCallback &&_doneCallback, CancelCond &&_cancelCond, const CBLSSignature &_sig, const CBLSPublicKey &_pubKey, const uint256 &_msgHash)
Definition: bls_worker.h:38
std::shared_ptr< BLSVerificationVector > BLSVerificationVectorPtr
Definition: bls.h:471
bool VerifyVerificationVectors(const std::vector< BLSVerificationVectorPtr > &vvecs, size_t start=0, size_t count=0)
Definition: bls_worker.cpp:793
std::vector< CBLSId > BLSIdVector
Definition: bls.h:464
void AsyncAggregatePublicKeys(const BLSPublicKeyVector &pubKeys, size_t start, size_t count, bool parallel, std::function< void(const CBLSPublicKey &)> doneCallback)
Definition: bls_worker.cpp:676
bool VerifySignatureVector(const BLSSignatureVector &sigs, size_t start=0, size_t count=0)
Definition: bls_worker.cpp:828
CBLSWorkerCache(CBLSWorker &_worker)
Definition: bls_worker.h:161
CBLSPublicKey BuildPubKeyShare(const BLSVerificationVectorPtr &vvec, const CBLSId &id)
Definition: bls_worker.cpp:719
std::function< void(const CBLSSignature &)> SignDoneCallback
Definition: bls_worker.h:24
void Stop()
Definition: bls_worker.cpp:69
std::vector< bool > VerifyContributionShares(const CBLSId &forId, const std::vector< BLSVerificationVectorPtr > &vvecs, const BLSSecretKeyVector &skShares, bool parallel=true, bool aggregated=true)
Definition: bls_worker.cpp:748
CBLSSecretKey AggregateSecretKeys(const BLSSecretKeyVector &secKeys, size_t start=0, size_t count=0, bool parallel=true)
Definition: bls_worker.cpp:670
CBLSPublicKey BuildPubKeyShare(const uint256 &cacheKey, const BLSVerificationVectorPtr &vvec, const CBLSId &id)
Definition: bls_worker.h:176
std::function< bool()> CancelCond
Definition: bls_worker.h:26
void PushSigVerifyBatch()
Definition: bls_worker.cpp:891
void Start()
Definition: bls_worker.cpp:61
std::map< uint256, std::shared_future< BLSVerificationVectorPtr > > vvecCache
Definition: bls_worker.h:156
256-bit opaque blob.
Definition: uint256.h:123
bool IsAsyncVerifyInProgress()
Definition: bls_worker.cpp:884
void AsyncVerifySig(const CBLSSignature &sig, const CBLSPublicKey &pubKey, const uint256 &msgHash, SigVerifyDoneCallback doneCallback, CancelCond cancelCond=[] { return false;})
Definition: bls_worker.cpp:847
std::map< uint256, std::shared_future< CBLSPublicKey > > publicKeyShareCache
Definition: bls_worker.h:158
CBLSWorker & worker
Definition: bls_worker.h:153
void AsyncAggregateSecretKeys(const BLSSecretKeyVector &secKeys, size_t start, size_t count, bool parallel, std::function< void(const CBLSSecretKey &)> doneCallback)
Definition: bls_worker.cpp:655
void AsyncSign(const CBLSSecretKey &secKey, const uint256 &msgHash, SignDoneCallback doneCallback)
Definition: bls_worker.cpp:833
static int count
Definition: tests.c:45
std::future< bool > AsyncVerifyContributionShare(const CBLSId &forId, const BLSVerificationVectorPtr &vvec, const CBLSSecretKey &skContribution)
Definition: bls_worker.cpp:754
CBLSSignature AggregateSigs(const BLSSignatureVector &sigs, size_t start=0, size_t count=0, bool parallel=true)
Definition: bls_worker.cpp:712
BLSVerificationVectorPtr BuildQuorumVerificationVector(const uint256 &cacheKey, const std::vector< BLSVerificationVectorPtr > &vvecs)
Definition: bls_worker.h:164
std::vector< SigVerifyJob > sigVerifyQueue
Definition: bls_worker.h:50
void AsyncAggregateSigs(const BLSSignatureVector &sigs, size_t start, size_t count, bool parallel, std::function< void(const CBLSSignature &)> doneCallback)
Definition: bls_worker.cpp:697
Released under the MIT license