Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

bls.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2019 The Dash Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <bls/bls.h>
6 
7 #include <hash.h>
8 #include <random.h>
9 #include <tinyformat.h>
10 
11 #ifndef BUILD_BITCOIN_INTERNAL
13 #endif
14 
15 #include <assert.h>
16 #include <string.h>
17 
18 bool CBLSId::InternalSetBuf(const void* buf)
19 {
20  memcpy(impl.begin(), buf, sizeof(uint256));
21  return true;
22 }
23 
24 bool CBLSId::InternalGetBuf(void* buf) const
25 {
26  memcpy(buf, impl.begin(), sizeof(uint256));
27  return true;
28 }
29 
30 void CBLSId::SetInt(int x)
31 {
32  impl.SetHex(strprintf("%x", x));
33  fValid = true;
34  UpdateHash();
35 }
36 
37 void CBLSId::SetHash(const uint256& hash)
38 {
39  impl = hash;
40  fValid = true;
41  UpdateHash();
42 }
43 
45 {
46  CBLSId id;
47  id.SetInt(i);
48  return id;
49 }
50 
52 {
53  CBLSId id;
54  id.SetHash(hash);
55  return id;
56 }
57 
58 bool CBLSSecretKey::InternalSetBuf(const void* buf)
59 {
60  try {
61  impl = bls::PrivateKey::FromBytes((const uint8_t*)buf);
62  return true;
63  } catch (...) {
64  return false;
65  }
66 }
67 
68 bool CBLSSecretKey::InternalGetBuf(void* buf) const
69 {
70  impl.Serialize((uint8_t*)buf);
71  return true;
72 }
73 
75 {
76  assert(IsValid() && o.IsValid());
77  impl = bls::PrivateKey::AggregateInsecure({impl, o.impl});
78  UpdateHash();
79 }
80 
81 CBLSSecretKey CBLSSecretKey::AggregateInsecure(const std::vector<CBLSSecretKey>& sks)
82 {
83  if (sks.empty()) {
84  return CBLSSecretKey();
85  }
86 
87  std::vector<bls::PrivateKey> v;
88  v.reserve(sks.size());
89  for (auto& sk : sks) {
90  v.emplace_back(sk.impl);
91  }
92 
93  auto agg = bls::PrivateKey::AggregateInsecure(v);
94  CBLSSecretKey ret;
95  ret.impl = agg;
96  ret.fValid = true;
97  ret.UpdateHash();
98  return ret;
99 }
100 
101 #ifndef BUILD_BITCOIN_INTERNAL
103 {
104  unsigned char buf[32];
105  while (true) {
106  GetStrongRandBytes(buf, sizeof(buf));
107  try {
108  impl = bls::PrivateKey::FromBytes((const uint8_t*)buf);
109  break;
110  } catch (...) {
111  }
112  }
113  fValid = true;
114  UpdateHash();
115 }
116 #endif
117 
118 bool CBLSSecretKey::SecretKeyShare(const std::vector<CBLSSecretKey>& msk, const CBLSId& _id)
119 {
120  fValid = false;
121  UpdateHash();
122 
123  if (!_id.IsValid()) {
124  return false;
125  }
126 
127  std::vector<bls::PrivateKey> mskVec;
128  mskVec.reserve(msk.size());
129  for (const CBLSSecretKey& sk : msk) {
130  if (!sk.IsValid()) {
131  return false;
132  }
133  mskVec.emplace_back(sk.impl);
134  }
135 
136  try {
137  impl = bls::BLS::PrivateKeyShare(mskVec, (const uint8_t*)_id.impl.begin());
138  } catch (...) {
139  return false;
140  }
141 
142  fValid = true;
143  UpdateHash();
144  return true;
145 }
146 
148 {
149  if (!IsValid()) {
150  return CBLSPublicKey();
151  }
152 
153  CBLSPublicKey pubKey;
154  pubKey.impl = impl.GetPublicKey();
155  pubKey.fValid = true;
156  pubKey.UpdateHash();
157  return pubKey;
158 }
159 
161 {
162  if (!IsValid()) {
163  return CBLSSignature();
164  }
165 
166  CBLSSignature sigRet;
167  sigRet.impl = impl.SignInsecurePrehashed((const uint8_t*)hash.begin());
168 
169  sigRet.fValid = true;
170  sigRet.UpdateHash();
171 
172  return sigRet;
173 }
174 
175 bool CBLSPublicKey::InternalSetBuf(const void* buf)
176 {
177  try {
178  impl = bls::PublicKey::FromBytes((const uint8_t*)buf);
179  return true;
180  } catch (...) {
181  return false;
182  }
183 }
184 
185 bool CBLSPublicKey::InternalGetBuf(void* buf) const
186 {
187  impl.Serialize((uint8_t*)buf);
188  return true;
189 }
190 
192 {
193  assert(IsValid() && o.IsValid());
194  impl = bls::PublicKey::AggregateInsecure({impl, o.impl});
195  UpdateHash();
196 }
197 
198 CBLSPublicKey CBLSPublicKey::AggregateInsecure(const std::vector<CBLSPublicKey>& pks)
199 {
200  if (pks.empty()) {
201  return CBLSPublicKey();
202  }
203 
204  std::vector<bls::PublicKey> v;
205  v.reserve(pks.size());
206  for (auto& pk : pks) {
207  v.emplace_back(pk.impl);
208  }
209 
210  auto agg = bls::PublicKey::AggregateInsecure(v);
211  CBLSPublicKey ret;
212  ret.impl = agg;
213  ret.fValid = true;
214  ret.UpdateHash();
215  return ret;
216 }
217 
218 bool CBLSPublicKey::PublicKeyShare(const std::vector<CBLSPublicKey>& mpk, const CBLSId& _id)
219 {
220  fValid = false;
221  UpdateHash();
222 
223  if (!_id.IsValid()) {
224  return false;
225  }
226 
227  std::vector<bls::PublicKey> mpkVec;
228  mpkVec.reserve(mpk.size());
229  for (const CBLSPublicKey& pk : mpk) {
230  if (!pk.IsValid()) {
231  return false;
232  }
233  mpkVec.emplace_back(pk.impl);
234  }
235 
236  try {
237  impl = bls::BLS::PublicKeyShare(mpkVec, (const uint8_t*)_id.impl.begin());
238  } catch (...) {
239  return false;
240  }
241 
242  fValid = true;
243  UpdateHash();
244  return true;
245 }
246 
248 {
249  fValid = false;
250  UpdateHash();
251 
252  if (!sk.IsValid() || !pk.IsValid()) {
253  return false;
254  }
255  impl = bls::BLS::DHKeyExchange(sk.impl, pk.impl);
256  fValid = true;
257  UpdateHash();
258  return true;
259 }
260 
261 bool CBLSSignature::InternalSetBuf(const void* buf)
262 {
263  try {
264  impl = bls::InsecureSignature::FromBytes((const uint8_t*)buf);
265  return true;
266  } catch (...) {
267  return false;
268  }
269 }
270 
271 bool CBLSSignature::InternalGetBuf(void* buf) const
272 {
273  impl.Serialize((uint8_t*)buf);
274  return true;
275 }
276 
278 {
279  assert(IsValid() && o.IsValid());
280  impl = bls::InsecureSignature::Aggregate({impl, o.impl});
281  UpdateHash();
282 }
283 
284 CBLSSignature CBLSSignature::AggregateInsecure(const std::vector<CBLSSignature>& sigs)
285 {
286  if (sigs.empty()) {
287  return CBLSSignature();
288  }
289 
290  std::vector<bls::InsecureSignature> v;
291  v.reserve(sigs.size());
292  for (auto& pk : sigs) {
293  v.emplace_back(pk.impl);
294  }
295 
296  auto agg = bls::InsecureSignature::Aggregate(v);
297  CBLSSignature ret;
298  ret.impl = agg;
299  ret.fValid = true;
300  ret.UpdateHash();
301  return ret;
302 }
303 
304 CBLSSignature CBLSSignature::AggregateSecure(const std::vector<CBLSSignature>& sigs,
305  const std::vector<CBLSPublicKey>& pks,
306  const uint256& hash)
307 {
308  if (sigs.size() != pks.size() || sigs.empty()) {
309  return CBLSSignature();
310  }
311 
312  std::vector<bls::Signature> v;
313  v.reserve(sigs.size());
314 
315  for (size_t i = 0; i < sigs.size(); i++) {
316  bls::AggregationInfo aggInfo = bls::AggregationInfo::FromMsgHash(pks[i].impl, hash.begin());
317  v.emplace_back(bls::Signature::FromInsecureSig(sigs[i].impl, aggInfo));
318  }
319 
320  auto aggSig = bls::Signature::AggregateSigs(v);
321  CBLSSignature ret;
322  ret.impl = aggSig.GetInsecureSig();
323  ret.fValid = true;
324  ret.UpdateHash();
325  return ret;
326 }
327 
329 {
330  assert(IsValid() && o.IsValid());
331  impl = impl.DivideBy({o.impl});
332  UpdateHash();
333 }
334 
335 bool CBLSSignature::VerifyInsecure(const CBLSPublicKey& pubKey, const uint256& hash) const
336 {
337  if (!IsValid() || !pubKey.IsValid()) {
338  return false;
339  }
340 
341  try {
342  return impl.Verify({(const uint8_t*)hash.begin()}, {pubKey.impl});
343  } catch (...) {
344  return false;
345  }
346 }
347 
348 bool CBLSSignature::VerifyInsecureAggregated(const std::vector<CBLSPublicKey>& pubKeys, const std::vector<uint256>& hashes) const
349 {
350  if (!IsValid()) {
351  return false;
352  }
353  assert(!pubKeys.empty() && !hashes.empty() && pubKeys.size() == hashes.size());
354 
355  std::vector<bls::PublicKey> pubKeyVec;
356  std::vector<const uint8_t*> hashes2;
357  hashes2.reserve(hashes.size());
358  pubKeyVec.reserve(pubKeys.size());
359  for (size_t i = 0; i < pubKeys.size(); i++) {
360  auto& p = pubKeys[i];
361  if (!p.IsValid()) {
362  return false;
363  }
364  pubKeyVec.push_back(p.impl);
365  hashes2.push_back((uint8_t*)hashes[i].begin());
366  }
367 
368  try {
369  return impl.Verify(hashes2, pubKeyVec);
370  } catch (...) {
371  return false;
372  }
373 }
374 
375 bool CBLSSignature::VerifySecureAggregated(const std::vector<CBLSPublicKey>& pks, const uint256& hash) const
376 {
377  if (pks.empty()) {
378  return false;
379  }
380 
381  std::vector<bls::AggregationInfo> v;
382  v.reserve(pks.size());
383  for (auto& pk : pks) {
384  auto aggInfo = bls::AggregationInfo::FromMsgHash(pk.impl, hash.begin());
385  v.emplace_back(aggInfo);
386  }
387 
388  bls::AggregationInfo aggInfo = bls::AggregationInfo::MergeInfos(v);
389  bls::Signature aggSig = bls::Signature::FromInsecureSig(impl, aggInfo);
390  return aggSig.Verify();
391 }
392 
393 bool CBLSSignature::Recover(const std::vector<CBLSSignature>& sigs, const std::vector<CBLSId>& ids)
394 {
395  fValid = false;
396  UpdateHash();
397 
398  if (sigs.empty() || ids.empty() || sigs.size() != ids.size()) {
399  return false;
400  }
401 
402  std::vector<bls::InsecureSignature> sigsVec;
403  std::vector<const uint8_t*> idsVec;
404  sigsVec.reserve(sigs.size());
405  idsVec.reserve(sigs.size());
406 
407  for (size_t i = 0; i < sigs.size(); i++) {
408  if (!sigs[i].IsValid() || !ids[i].IsValid()) {
409  return false;
410  }
411  sigsVec.emplace_back(sigs[i].impl);
412  idsVec.emplace_back(ids[i].impl.begin());
413  }
414 
415  try {
416  impl = bls::BLS::RecoverSig(sigsVec, idsVec);
417  } catch (...) {
418  return false;
419  }
420 
421  fValid = true;
422  UpdateHash();
423  return true;
424 }
425 
426 #ifndef BUILD_BITCOIN_INTERNAL
427 
428 static std::once_flag init_flag;
431 {
432  // make sure LockedPoolManager is initialized first (ensures destruction order)
434 
435  // static variable in function scope ensures it's initialized when first accessed
436  // and destroyed before LockedPoolManager
437  static mt_pooled_secure_allocator<uint8_t> a(sizeof(bn_t) + sizeof(size_t));
439 }
440 
442 {
443  std::call_once(init_flag, create_secure_allocator);
445 }
446 
447 static void* secure_allocate(size_t n)
448 {
449  uint8_t* ptr = get_secure_allocator().allocate(n + sizeof(size_t));
450  *(size_t*)ptr = n;
451  return ptr + sizeof(size_t);
452 }
453 
454 static void secure_free(void* p)
455 {
456  if (!p) {
457  return;
458  }
459 
460  uint8_t* ptr = (uint8_t*)p - sizeof(size_t);
461  size_t n = *(size_t*)ptr;
462  return get_secure_allocator().deallocate(ptr, n);
463 }
464 #endif
465 
466 bool BLSInit()
467 {
468 #ifndef BUILD_BITCOIN_INTERNAL
469  bls::BLS::SetSecureAllocator(secure_allocate, secure_free);
470 #endif
471  return true;
472 }
bool InternalSetBuf(const void *buf)
Definition: bls.cpp:175
bool SecretKeyShare(const std::vector< CBLSSecretKey > &msk, const CBLSId &id)
Definition: bls.cpp:118
static CBLSId FromInt(int64_t i)
Definition: bls.cpp:44
bool InternalGetBuf(void *buf) const
Definition: bls.cpp:185
static LockedPoolManager & Instance()
Return the current instance, or create it once.
Definition: lockedpool.h:213
#define strprintf
Definition: tinyformat.h:1066
static CBLSSignature AggregateSecure(const std::vector< CBLSSignature > &sigs, const std::vector< CBLSPublicKey > &pks, const uint256 &hash)
Definition: bls.cpp:304
void SubInsecure(const CBLSSignature &o)
Definition: bls.cpp:328
static void create_secure_allocator()
Definition: bls.cpp:430
void GetStrongRandBytes(unsigned char *out, int num)
Function to gather random data from multiple sources, failing whenever any of those source fail to pr...
Definition: random.cpp:317
bool VerifyInsecure(const CBLSPublicKey &pubKey, const uint256 &hash) const
Definition: bls.cpp:335
void AggregateInsecure(const CBLSSecretKey &o)
Definition: bls.cpp:74
static CBLSId FromHash(const uint256 &hash)
Definition: bls.cpp:51
unsigned char * begin()
Definition: uint256.h:57
void MakeNewKey()
Definition: bls.cpp:102
bool VerifyInsecureAggregated(const std::vector< CBLSPublicKey > &pubKeys, const std::vector< uint256 > &hashes) const
Definition: bls.cpp:348
static void secure_free(void *p)
Definition: bls.cpp:454
Definition: bls.h:218
void SetHash(const uint256 &hash)
Definition: bls.cpp:37
CBLSSignature()
Definition: bls.h:295
std::size_t size_t
Definition: bits.hpp:21
static std::once_flag init_flag
Definition: bls.cpp:428
CBLSSecretKey()
Definition: bls.h:245
bool InternalSetBuf(const void *buf)
Definition: bls.cpp:261
static mt_pooled_secure_allocator< uint8_t > * secure_allocator_instance
Definition: bls.cpp:429
256-bit opaque blob.
Definition: uint256.h:123
void SetInt(int x)
Definition: bls.cpp:30
bool PublicKeyShare(const std::vector< CBLSPublicKey > &mpk, const CBLSId &id)
Definition: bls.cpp:218
bool InternalSetBuf(const void *buf)
Definition: bls.cpp:18
bool DHKeyExchange(const CBLSSecretKey &sk, const CBLSPublicKey &pk)
Definition: bls.cpp:247
void AggregateInsecure(const CBLSPublicKey &o)
Definition: bls.cpp:191
void AggregateInsecure(const CBLSSignature &o)
Definition: bls.cpp:277
void * memcpy(void *a, const void *b, size_t c)
CBLSPublicKey GetPublicKey() const
Definition: bls.cpp:147
bool InternalGetBuf(void *buf) const
Definition: bls.cpp:68
bool InternalSetBuf(const void *buf)
Definition: bls.cpp:58
bool InternalGetBuf(void *buf) const
Definition: bls.cpp:24
static mt_pooled_secure_allocator< uint8_t > & get_secure_allocator()
Definition: bls.cpp:441
bool Recover(const std::vector< CBLSSignature > &sigs, const std::vector< CBLSId > &ids)
Definition: bls.cpp:393
bool InternalGetBuf(void *buf) const
Definition: bls.cpp:271
void SetHex(const char *psz)
Definition: uint256.cpp:27
bool VerifySecureAggregated(const std::vector< CBLSPublicKey > &pks, const uint256 &hash) const
Definition: bls.cpp:375
CBLSPublicKey()
Definition: bls.h:273
CBLSSignature Sign(const uint256 &hash) const
Definition: bls.cpp:160
static void * secure_allocate(size_t n)
Definition: bls.cpp:447
bool BLSInit()
Definition: bls.cpp:466
Released under the MIT license