Ring Daemon 16.0.0
Loading...
Searching...
No Matches
FixedHash.h
Go to the documentation of this file.
1/*
2 This file is part of cpp-ethereum.
3
4 cpp-ethereum is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 cpp-ethereum is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16*/
24#pragma once
25
26#include <array>
27#include <cstdint>
28#include <algorithm>
29#include <random>
30#include <opendht/rng.h>
31
32#include "CommonData.h"
33
34namespace dev {
35
37template<unsigned N>
39{
40 enum { result = 1 + StaticLog2<N / 2>::result };
41};
42template<>
43struct StaticLog2<1>
44{
45 enum { result = 0 };
46};
47
51template<unsigned N>
53{
54public:
56 enum { size = N };
57
60
63
66
68 FixedHash() { m_data.fill(0); }
69
71 template<unsigned M>
73 {
74 m_data.fill(0);
75 unsigned c = std::min(M, N);
76 for (unsigned i = 0; i < c; ++i)
77 m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i];
78 }
79
81 explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); }
82
85 {
86 if (_b.size() == N)
87 memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N));
88 else {
89 m_data.fill(0);
90 if (_t != FailIfDifferent) {
91 auto c = std::min<unsigned>(_b.size(), N);
92 for (unsigned i = 0; i < c; ++i)
93 m_data[_t == AlignRight ? N - 1 - i : i]
94 = _b[_t == AlignRight ? _b.size() - 1 - i : i];
95 }
96 }
97 }
98
101 {
102 if (_b.size() == N)
103 memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N));
104 else {
105 m_data.fill(0);
106 if (_t != FailIfDifferent) {
107 auto c = std::min<unsigned>(_b.size(), N);
108 for (unsigned i = 0; i < c; ++i)
109 m_data[_t == AlignRight ? N - 1 - i : i]
110 = _b[_t == AlignRight ? _b.size() - 1 - i : i];
111 }
112 }
113 }
114
116 explicit FixedHash(uint8_t const* _bs, ConstructFromPointerType)
117 {
118 memcpy(m_data.data(), _bs, N);
119 }
120
122 explicit FixedHash(std::string const& _s,
125 : FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht)
126 {}
127
129 explicit operator bool() const
130 {
131 return std::any_of(m_data.begin(), m_data.end(), [](uint8_t _b) { return _b != 0; });
132 }
133
134 // The obvious comparison operators.
135 bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }
136 bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }
137 bool operator<(FixedHash const& _c) const
138 {
139 for (unsigned i = 0; i < N; ++i)
140 if (m_data[i] < _c.m_data[i])
141 return true;
142 else if (m_data[i] > _c.m_data[i])
143 return false;
144 return false;
145 }
146 bool operator>=(FixedHash const& _c) const { return !operator<(_c); }
147 bool operator<=(FixedHash const& _c) const { return operator==(_c) || operator<(_c); }
148 bool operator>(FixedHash const& _c) const { return !operator<=(_c); }
149
150 // The obvious binary operators.
152 {
153 for (unsigned i = 0; i < N; ++i)
154 m_data[i] ^= _c.m_data[i];
155 return *this;
156 }
157 FixedHash operator^(FixedHash const& _c) const { return FixedHash(*this) ^= _c; }
159 {
160 for (unsigned i = 0; i < N; ++i)
161 m_data[i] |= _c.m_data[i];
162 return *this;
163 }
164 FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; }
166 {
167 for (unsigned i = 0; i < N; ++i)
168 m_data[i] &= _c.m_data[i];
169 return *this;
170 }
171 FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
173 {
174 FixedHash ret;
175 for (unsigned i = 0; i < N; ++i)
176 ret[i] = ~m_data[i];
177 return ret;
178 }
179
180 // Big-endian increment.
182 {
183 for (unsigned i = size; i > 0 && !++m_data[--i];) {
184 }
185 return *this;
186 }
187
189 bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }
190
192 uint8_t& operator[](unsigned _i) { return m_data[_i]; }
194 uint8_t operator[](unsigned _i) const { return m_data[_i]; }
195
197 std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; }
198
200 std::string abridgedMiddle() const
201 {
202 return toHex(ref().cropped(0, 4)) + "\342\200\246" + toHex(ref().cropped(N - 4));
203 }
204
206 std::string hex() const { return toHex(ref()); }
207
209 bytesRef ref() { return bytesRef(m_data.data(), N); }
210
212 bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }
213
215 uint8_t* data() { return m_data.data(); }
216
218 uint8_t const* data() const { return m_data.data(); }
219
221 auto begin() const -> typename std::array<uint8_t, N>::const_iterator { return m_data.begin(); }
222
224 auto end() const -> typename std::array<uint8_t, N>::const_iterator { return m_data.end(); }
225
227 bytes asBytes() const { return bytes(data(), data() + N); }
228
230 std::array<uint8_t, N>& asArray() { return m_data; }
231
233 std::array<uint8_t, N> const& asArray() const { return m_data; }
234
236 template<class Engine>
237 void randomize(Engine& _eng)
238 {
239 for (auto& i : m_data)
240 i = (uint8_t) std::uniform_int_distribution<uint16_t>(0, 255)(_eng);
241 }
242
245 {
246 FixedHash ret;
247 std::random_device rd;
248 ret.randomize(rd);
249 return ret;
250 }
251
252 template<unsigned P, unsigned M>
254 {
255 return (*this |= _h.template bloomPart<P, N>());
256 }
257
258 template<unsigned P, unsigned M>
259 inline bool containsBloom(FixedHash<M> const& _h)
260 {
261 return contains(_h.template bloomPart<P, N>());
262 }
263
264 template<unsigned P, unsigned M>
265 inline FixedHash<M> bloomPart() const
266 {
267 unsigned const c_bloomBits = M * 8;
268 unsigned const c_mask = c_bloomBits - 1;
269 unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8;
270
271 static_assert((M & (M - 1)) == 0, "M must be power-of-two");
272 static_assert(P * c_bloomBytes <= N, "out of range");
273
274 FixedHash<M> ret;
275 uint8_t const* p = data();
276 for (unsigned i = 0; i < P; ++i) {
277 unsigned index = 0;
278 for (unsigned j = 0; j < c_bloomBytes; ++j, ++p)
279 index = (index << 8) | *p;
280 index &= c_mask;
281 ret[M - 1 - index / 8] |= (1 << (index % 8));
282 }
283 return ret;
284 }
285
287 inline unsigned firstBitSet() const
288 {
289 unsigned ret = 0;
290 for (auto d : m_data)
291 if (d)
292 for (;; ++ret, d <<= 1)
293 if (d & 0x80)
294 return ret;
295 else {
296 }
297 else
298 ret += 8;
299 return ret;
300 }
301
302 void clear() { m_data.fill(0); }
303
304private:
305 std::array<uint8_t, N> m_data;
306};
307
308template<unsigned T>
309class SecureFixedHash : private FixedHash<T>
310{
311public:
315 SecureFixedHash() = default;
316 explicit SecureFixedHash(bytes const& _b,
318 : FixedHash<T>(_b, _t)
319 {}
324 template<unsigned M>
325 explicit SecureFixedHash(FixedHash<M> const& _h,
327 : FixedHash<T>(_h, _t)
328 {}
332 template<unsigned M>
337 explicit SecureFixedHash(std::string const& _s,
340 : FixedHash<T>(_s, _t, _ht)
341 {}
343 : FixedHash<T>(_d, _t)
344 {}
346
348 {
349 if (&_c == this)
350 return *this;
351 ref().cleanse();
352 FixedHash<T>::operator=(static_cast<FixedHash<T> const&>(_c));
353 return *this;
354 }
355
356 using FixedHash<T>::size;
357
358 FixedHash<T> const& makeInsecure() const { return static_cast<FixedHash<T> const&>(*this); }
360 {
361 clear();
362 return static_cast<FixedHash<T>&>(*this);
363 }
364
365 using FixedHash<T>::operator bool;
366
367 // The obvious comparison operators.
368 bool operator==(SecureFixedHash const& _c) const
369 {
370 return static_cast<FixedHash<T> const&>(*this).operator==(
371 static_cast<FixedHash<T> const&>(_c));
372 }
373 bool operator!=(SecureFixedHash const& _c) const
374 {
375 return static_cast<FixedHash<T> const&>(*this).operator!=(
376 static_cast<FixedHash<T> const&>(_c));
377 }
378 bool operator<(SecureFixedHash const& _c) const
379 {
380 return static_cast<FixedHash<T> const&>(*this).operator<(
381 static_cast<FixedHash<T> const&>(_c));
382 }
383 bool operator>=(SecureFixedHash const& _c) const
384 {
385 return static_cast<FixedHash<T> const&>(*this).operator>=(
386 static_cast<FixedHash<T> const&>(_c));
387 }
388 bool operator<=(SecureFixedHash const& _c) const
389 {
390 return static_cast<FixedHash<T> const&>(*this).operator<=(
391 static_cast<FixedHash<T> const&>(_c));
392 }
393 bool operator>(SecureFixedHash const& _c) const
394 {
395 return static_cast<FixedHash<T> const&>(*this).operator>(
396 static_cast<FixedHash<T> const&>(_c));
397 }
398
399 using FixedHash<T>::operator==;
400 using FixedHash<T>::operator!=;
401 using FixedHash<T>::operator<;
402 using FixedHash<T>::operator>=;
403 using FixedHash<T>::operator<=;
404 using FixedHash<T>::operator>;
405
406 // The obvious binary operators.
408 {
409 static_cast<FixedHash<T>&>(*this).operator^=(_c);
410 return *this;
411 }
412 SecureFixedHash operator^(FixedHash<T> const& _c) const { return SecureFixedHash(*this) ^= _c; }
414 {
415 static_cast<FixedHash<T>&>(*this).operator^=(_c);
416 return *this;
417 }
418 SecureFixedHash operator|(FixedHash<T> const& _c) const { return SecureFixedHash(*this) |= _c; }
420 {
421 static_cast<FixedHash<T>&>(*this).operator^=(_c);
422 return *this;
423 }
424 SecureFixedHash operator&(FixedHash<T> const& _c) const { return SecureFixedHash(*this) &= _c; }
425
427 {
428 static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c));
429 return *this;
430 }
432 {
433 return SecureFixedHash(*this) ^= _c;
434 }
436 {
437 static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c));
438 return *this;
439 }
441 {
442 return SecureFixedHash(*this) |= _c;
443 }
445 {
446 static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c));
447 return *this;
448 }
450 {
451 return SecureFixedHash(*this) &= _c;
452 }
454 {
455 auto r = ~static_cast<FixedHash<T> const&>(*this);
456 return static_cast<SecureFixedHash const&>(r);
457 }
458
459 using FixedHash<T>::abridged;
461
462 bytesConstRef ref() const { return FixedHash<T>::ref(); }
463 uint8_t const* data() const { return FixedHash<T>::data(); }
464
466 {
468 std::random_device rd;
469 ret.randomize(rd);
470 return ret;
471 }
472 using FixedHash<T>::firstBitSet;
473
474 void clear() { ref().cleanse(); }
475};
476
478template<>
479inline bool
481{
482 const uint64_t* hash1 = (const uint64_t*) data();
483 const uint64_t* hash2 = (const uint64_t*) _other.data();
484 return (hash1[0] == hash2[0]) && (hash1[1] == hash2[1]) && (hash1[2] == hash2[2])
485 && (hash1[3] == hash2[3]);
486}
487
488// Common types of FixedHash.
497using h512s = std::vector<h512>;
498using h256s = std::vector<h256>;
499using h160s = std::vector<h160>;
500using h256Set = std::set<h256>;
501using h160Set = std::set<h160>;
502using h256Hash = std::unordered_set<h256>;
503using h160Hash = std::unordered_set<h160>;
504
506inline h160
507right160(h256 const& _t)
508{
509 h160 ret;
510 memcpy(ret.data(), _t.data() + 12, 20);
511 return ret;
512}
513
514} // namespace dev
#define P
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
Definition FixedHash.h:53
ConstructFromHashType
Method to convert from a string.
Definition FixedHash.h:65
bool operator<(FixedHash const &_c) const
Definition FixedHash.h:137
void randomize(Engine &_eng)
Populate with random data.
Definition FixedHash.h:237
bool contains(FixedHash const &_c) const
Definition FixedHash.h:189
FixedHash(bytesConstRef _b, ConstructFromHashType _t=FailIfDifferent)
Explicitly construct, copying from a byte array.
Definition FixedHash.h:100
bytesRef ref()
Definition FixedHash.h:209
bool containsBloom(FixedHash< M > const &_h)
Definition FixedHash.h:259
std::string hex() const
Definition FixedHash.h:206
bytes asBytes() const
Definition FixedHash.h:227
unsigned firstBitSet() const
Returns the index of the first bit set to one, or size() * 8 if no bits are set.
Definition FixedHash.h:287
FixedHash(unsigned _u)
Convert from unsigned.
Definition FixedHash.h:81
bytesConstRef ref() const
Definition FixedHash.h:212
FixedHash(FixedHash< M > const &_h, ConstructFromHashType _t=AlignLeft)
Construct from another hash, filling with zeroes or cropping as necessary.
Definition FixedHash.h:72
FixedHash & operator++()
Definition FixedHash.h:181
std::array< uint8_t, N > const & asArray() const
Definition FixedHash.h:233
std::array< uint8_t, N > & asArray()
Definition FixedHash.h:230
bool operator==(FixedHash const &_c) const
Definition FixedHash.h:135
ConstructFromPointerType
A dummy flag to avoid accidental construction from pointer.
Definition FixedHash.h:59
auto end() const -> typename std::array< uint8_t, N >::const_iterator
Definition FixedHash.h:224
ConstructFromStringType
Method to convert from a string.
Definition FixedHash.h:62
FixedHash(std::string const &_s, ConstructFromStringType _t=FromHex, ConstructFromHashType _ht=FailIfDifferent)
Explicitly construct, copying from a string.
Definition FixedHash.h:122
FixedHash()
Construct an empty hash.
Definition FixedHash.h:68
FixedHash(bytes const &_b, ConstructFromHashType _t=FailIfDifferent)
Explicitly construct, copying from a byte array.
Definition FixedHash.h:84
FixedHash & shiftBloom(FixedHash< M > const &_h)
Definition FixedHash.h:253
FixedHash< M > bloomPart() const
Definition FixedHash.h:265
uint8_t * data()
Definition FixedHash.h:215
FixedHash(uint8_t const *_bs, ConstructFromPointerType)
Explicitly construct, copying from a bytes in memory with given pointer.
Definition FixedHash.h:116
bool operator>=(FixedHash const &_c) const
Definition FixedHash.h:146
FixedHash & operator^=(FixedHash const &_c)
Definition FixedHash.h:151
FixedHash & operator&=(FixedHash const &_c)
Definition FixedHash.h:165
uint8_t operator[](unsigned _i) const
Definition FixedHash.h:194
uint8_t const * data() const
Definition FixedHash.h:218
FixedHash operator~() const
Definition FixedHash.h:172
auto begin() const -> typename std::array< uint8_t, N >::const_iterator
Definition FixedHash.h:221
uint8_t & operator[](unsigned _i)
Definition FixedHash.h:192
FixedHash operator^(FixedHash const &_c) const
Definition FixedHash.h:157
FixedHash operator|(FixedHash const &_c) const
Definition FixedHash.h:164
FixedHash & operator|=(FixedHash const &_c)
Definition FixedHash.h:158
std::string abridged() const
Definition FixedHash.h:197
bool operator!=(FixedHash const &_c) const
Definition FixedHash.h:136
std::string abridgedMiddle() const
Definition FixedHash.h:200
bool operator>(FixedHash const &_c) const
Definition FixedHash.h:148
static FixedHash random()
Definition FixedHash.h:244
FixedHash operator&(FixedHash const &_c) const
Definition FixedHash.h:171
bool operator<=(FixedHash const &_c) const
Definition FixedHash.h:147
SecureFixedHash operator&(SecureFixedHash const &_c) const
Definition FixedHash.h:449
SecureFixedHash operator^(SecureFixedHash const &_c) const
Definition FixedHash.h:431
SecureFixedHash & operator&=(SecureFixedHash const &_c)
Definition FixedHash.h:444
FixedHash< T > & writable()
Definition FixedHash.h:359
SecureFixedHash(SecureFixedHash< M > const &_h, ConstructFromHashType _t=FixedHash< T >::AlignLeft)
Definition FixedHash.h:333
static SecureFixedHash< T > random()
Definition FixedHash.h:465
bool operator>=(SecureFixedHash const &_c) const
Definition FixedHash.h:383
SecureFixedHash(SecureFixedHash< T > const &_h)
Definition FixedHash.h:329
bool operator>(SecureFixedHash const &_c) const
Definition FixedHash.h:393
SecureFixedHash(bytes const *_d, ConstructFromPointerType _t)
Definition FixedHash.h:342
bool operator<=(SecureFixedHash const &_c) const
Definition FixedHash.h:388
SecureFixedHash & operator^=(SecureFixedHash const &_c)
Definition FixedHash.h:426
SecureFixedHash(bytesConstRef _b, ConstructFromHashType _t=FixedHash< T >::FailIfDifferent)
Definition FixedHash.h:320
SecureFixedHash operator|(SecureFixedHash const &_c) const
Definition FixedHash.h:440
SecureFixedHash(FixedHash< M > const &_h, ConstructFromHashType _t=FixedHash< T >::AlignLeft)
Definition FixedHash.h:325
SecureFixedHash operator~() const
Definition FixedHash.h:453
SecureFixedHash operator&(FixedHash< T > const &_c) const
Definition FixedHash.h:424
typename FixedHash< T >::ConstructFromStringType ConstructFromStringType
Definition FixedHash.h:313
bool operator==(SecureFixedHash const &_c) const
Definition FixedHash.h:368
SecureFixedHash & operator^=(FixedHash< T > const &_c)
Definition FixedHash.h:407
SecureFixedHash()=default
SecureFixedHash< T > & operator=(SecureFixedHash< T > const &_c)
Definition FixedHash.h:347
bool operator<(SecureFixedHash const &_c) const
Definition FixedHash.h:378
SecureFixedHash & operator&=(FixedHash< T > const &_c)
Definition FixedHash.h:419
SecureFixedHash & operator|=(SecureFixedHash const &_c)
Definition FixedHash.h:435
SecureFixedHash(bytes const &_b, ConstructFromHashType _t=FixedHash< T >::FailIfDifferent)
Definition FixedHash.h:316
typename FixedHash< T >::ConstructFromHashType ConstructFromHashType
Definition FixedHash.h:312
typename FixedHash< T >::ConstructFromPointerType ConstructFromPointerType
Definition FixedHash.h:314
bytesConstRef ref() const
Definition FixedHash.h:462
FixedHash< T > const & makeInsecure() const
Definition FixedHash.h:358
SecureFixedHash(std::string const &_s, ConstructFromStringType _t=FixedHash< T >::FromHex, ConstructFromHashType _ht=FixedHash< T >::FailIfDifferent)
Definition FixedHash.h:337
SecureFixedHash & operator|=(FixedHash< T > const &_c)
Definition FixedHash.h:413
SecureFixedHash operator^(FixedHash< T > const &_c) const
Definition FixedHash.h:412
SecureFixedHash operator|(FixedHash< T > const &_c) const
Definition FixedHash.h:418
bool operator!=(SecureFixedHash const &_c) const
Definition FixedHash.h:373
uint8_t const * data() const
Definition FixedHash.h:463
A modifiable reference to an existing object or vector in memory.
Definition vector_ref.h:21
_T * data() const
Definition vector_ref.h:93
void cleanse()
Securely overwrite the memory.
Definition vector_ref.h:137
size_t size() const
Definition vector_ref.h:97
Definition Address.h:25
std::vector< h256 > h256s
Definition FixedHash.h:498
std::vector< h160 > h160s
Definition FixedHash.h:499
vector_ref< uint8_t const > bytesConstRef
std::vector< h512 > h512s
Definition FixedHash.h:497
std::set< h256 > h256Set
Definition FixedHash.h:500
vector_ref< uint8_t > bytesRef
std::vector< uint8_t > bytes
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
std::unordered_set< h160 > h160Hash
Definition FixedHash.h:503
WhenError
Definition CommonData.h:38
std::unordered_set< h256 > h256Hash
Definition FixedHash.h:502
std::set< h160 > h160Set
Definition FixedHash.h:501
std::string toHex(Iterator _it, Iterator _end, std::string _prefix)
Definition CommonData.h:45
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
Definition FixedHash.h:507
Compile-time calculation of Log2 of constant values.
Definition FixedHash.h:39