Ring Daemon
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] = _b[_t == AlignRight ? _b.size() - 1 - i : i];
94 }
95 }
96 }
97
100 {
101 if (_b.size() == N)
102 memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N));
103 else {
104 m_data.fill(0);
105 if (_t != FailIfDifferent) {
106 auto c = std::min<unsigned>(_b.size(), N);
107 for (unsigned i = 0; i < c; ++i)
108 m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i];
109 }
110 }
111 }
112
114 explicit FixedHash(uint8_t const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }
115
117 explicit FixedHash(std::string const& _s,
120 : FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht)
121 {}
122
124 explicit operator bool() const
125 {
126 return std::any_of(m_data.begin(), m_data.end(), [](uint8_t _b) { return _b != 0; });
127 }
128
129 // The obvious comparison operators.
130 bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }
131 bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }
132 bool operator<(FixedHash const& _c) const
133 {
134 for (unsigned i = 0; i < N; ++i)
135 if (m_data[i] < _c.m_data[i])
136 return true;
137 else if (m_data[i] > _c.m_data[i])
138 return false;
139 return false;
140 }
141 bool operator>=(FixedHash const& _c) const { return !operator<(_c); }
142 bool operator<=(FixedHash const& _c) const { return operator==(_c) || operator<(_c); }
143 bool operator>(FixedHash const& _c) const { return !operator<=(_c); }
144
145 // The obvious binary operators.
147 {
148 for (unsigned i = 0; i < N; ++i)
149 m_data[i] ^= _c.m_data[i];
150 return *this;
151 }
152 FixedHash operator^(FixedHash const& _c) const { return FixedHash(*this) ^= _c; }
154 {
155 for (unsigned i = 0; i < N; ++i)
156 m_data[i] |= _c.m_data[i];
157 return *this;
158 }
159 FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; }
161 {
162 for (unsigned i = 0; i < N; ++i)
163 m_data[i] &= _c.m_data[i];
164 return *this;
165 }
166 FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
168 {
169 FixedHash ret;
170 for (unsigned i = 0; i < N; ++i)
171 ret[i] = ~m_data[i];
172 return ret;
173 }
174
175 // Big-endian increment.
177 {
178 for (unsigned i = size; i > 0 && !++m_data[--i];) {
179 }
180 return *this;
181 }
182
184 bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }
185
187 uint8_t& operator[](unsigned _i) { return m_data[_i]; }
189 uint8_t operator[](unsigned _i) const { return m_data[_i]; }
190
192 std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; }
193
195 std::string abridgedMiddle() const
196 {
197 return toHex(ref().cropped(0, 4)) + "\342\200\246" + toHex(ref().cropped(N - 4));
198 }
199
201 std::string hex() const { return toHex(ref()); }
202
204 bytesRef ref() { return bytesRef(m_data.data(), N); }
205
207 bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }
208
210 uint8_t* data() { return m_data.data(); }
211
213 uint8_t const* data() const { return m_data.data(); }
214
216 auto begin() const -> typename std::array<uint8_t, N>::const_iterator { return m_data.begin(); }
217
219 auto end() const -> typename std::array<uint8_t, N>::const_iterator { return m_data.end(); }
220
222 bytes asBytes() const { return bytes(data(), data() + N); }
223
225 std::array<uint8_t, N>& asArray() { return m_data; }
226
228 std::array<uint8_t, N> const& asArray() const { return m_data; }
229
231 template<class Engine>
232 void randomize(Engine& _eng)
233 {
234 for (auto& i : m_data)
235 i = (uint8_t) std::uniform_int_distribution<uint16_t>(0, 255)(_eng);
236 }
237
240 {
241 FixedHash ret;
242 std::random_device rd;
243 ret.randomize(rd);
244 return ret;
245 }
246
247 template<unsigned P, unsigned M>
249 {
250 return (*this |= _h.template bloomPart<P, N>());
251 }
252
253 template<unsigned P, unsigned M>
254 inline bool containsBloom(FixedHash<M> const& _h)
255 {
256 return contains(_h.template bloomPart<P, N>());
257 }
258
259 template<unsigned P, unsigned M>
260 inline FixedHash<M> bloomPart() const
261 {
262 unsigned const c_bloomBits = M * 8;
263 unsigned const c_mask = c_bloomBits - 1;
264 unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8;
265
266 static_assert((M & (M - 1)) == 0, "M must be power-of-two");
267 static_assert(P * c_bloomBytes <= N, "out of range");
268
269 FixedHash<M> ret;
270 uint8_t const* p = data();
271 for (unsigned i = 0; i < P; ++i) {
272 unsigned index = 0;
273 for (unsigned j = 0; j < c_bloomBytes; ++j, ++p)
274 index = (index << 8) | *p;
275 index &= c_mask;
276 ret[M - 1 - index / 8] |= (1 << (index % 8));
277 }
278 return ret;
279 }
280
282 inline unsigned firstBitSet() const
283 {
284 unsigned ret = 0;
285 for (auto d : m_data)
286 if (d)
287 for (;; ++ret, d <<= 1)
288 if (d & 0x80)
289 return ret;
290 else {
291 }
292 else
293 ret += 8;
294 return ret;
295 }
296
297 void clear() { m_data.fill(0); }
298
299private:
300 std::array<uint8_t, N> m_data;
301};
302
303template<unsigned T>
304class SecureFixedHash : private FixedHash<T>
305{
306public:
310 SecureFixedHash() = default;
312 : FixedHash<T>(_b, _t)
313 {}
317 template<unsigned M>
319 : FixedHash<T>(_h, _t)
320 {}
324 template<unsigned M>
328 explicit SecureFixedHash(std::string const& _s,
331 : FixedHash<T>(_s, _t, _ht)
332 {}
334 : FixedHash<T>(_d, _t)
335 {}
337
339 {
340 if (&_c == this)
341 return *this;
342 ref().cleanse();
343 FixedHash<T>::operator=(static_cast<FixedHash<T> const&>(_c));
344 return *this;
345 }
346
347 using FixedHash<T>::size;
348
349 FixedHash<T> const& makeInsecure() const { return static_cast<FixedHash<T> const&>(*this); }
351 {
352 clear();
353 return static_cast<FixedHash<T>&>(*this);
354 }
355
356 using FixedHash<T>::operator bool;
357
358 // The obvious comparison operators.
359 bool operator==(SecureFixedHash const& _c) const
360 {
361 return static_cast<FixedHash<T> const&>(*this).operator==(static_cast<FixedHash<T> const&>(_c));
362 }
363 bool operator!=(SecureFixedHash const& _c) const
364 {
365 return static_cast<FixedHash<T> const&>(*this).operator!=(static_cast<FixedHash<T> const&>(_c));
366 }
367 bool operator<(SecureFixedHash const& _c) const
368 {
369 return static_cast<FixedHash<T> const&>(*this).operator<(static_cast<FixedHash<T> const&>(_c));
370 }
371 bool operator>=(SecureFixedHash const& _c) const
372 {
373 return static_cast<FixedHash<T> const&>(*this).operator>=(static_cast<FixedHash<T> const&>(_c));
374 }
375 bool operator<=(SecureFixedHash const& _c) const
376 {
377 return static_cast<FixedHash<T> const&>(*this).operator<=(static_cast<FixedHash<T> const&>(_c));
378 }
379 bool operator>(SecureFixedHash const& _c) const
380 {
381 return static_cast<FixedHash<T> const&>(*this).operator>(static_cast<FixedHash<T> const&>(_c));
382 }
383
384 using FixedHash<T>::operator==;
385 using FixedHash<T>::operator!=;
386 using FixedHash<T>::operator<;
387 using FixedHash<T>::operator>=;
388 using FixedHash<T>::operator<=;
389 using FixedHash<T>::operator>;
390
391 // The obvious binary operators.
393 {
394 static_cast<FixedHash<T>&>(*this).operator^=(_c);
395 return *this;
396 }
397 SecureFixedHash operator^(FixedHash<T> const& _c) const { return SecureFixedHash(*this) ^= _c; }
399 {
400 static_cast<FixedHash<T>&>(*this).operator^=(_c);
401 return *this;
402 }
403 SecureFixedHash operator|(FixedHash<T> const& _c) const { return SecureFixedHash(*this) |= _c; }
405 {
406 static_cast<FixedHash<T>&>(*this).operator^=(_c);
407 return *this;
408 }
409 SecureFixedHash operator&(FixedHash<T> const& _c) const { return SecureFixedHash(*this) &= _c; }
410
412 {
413 static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c));
414 return *this;
415 }
416 SecureFixedHash operator^(SecureFixedHash const& _c) const { return SecureFixedHash(*this) ^= _c; }
418 {
419 static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c));
420 return *this;
421 }
422 SecureFixedHash operator|(SecureFixedHash const& _c) const { return SecureFixedHash(*this) |= _c; }
424 {
425 static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c));
426 return *this;
427 }
428 SecureFixedHash operator&(SecureFixedHash const& _c) const { return SecureFixedHash(*this) &= _c; }
430 {
431 auto r = ~static_cast<FixedHash<T> const&>(*this);
432 return static_cast<SecureFixedHash const&>(r);
433 }
434
435 using FixedHash<T>::abridged;
437
438 bytesConstRef ref() const { return FixedHash<T>::ref(); }
439 uint8_t const* data() const { return FixedHash<T>::data(); }
440
442 {
444 std::random_device rd;
445 ret.randomize(rd);
446 return ret;
447 }
448 using FixedHash<T>::firstBitSet;
449
450 void clear() { ref().cleanse(); }
451};
452
454template<>
455inline bool
457{
458 const uint64_t* hash1 = (const uint64_t*) data();
459 const uint64_t* hash2 = (const uint64_t*) _other.data();
460 return (hash1[0] == hash2[0]) && (hash1[1] == hash2[1]) && (hash1[2] == hash2[2]) && (hash1[3] == hash2[3]);
461}
462
463// Common types of FixedHash.
472using h512s = std::vector<h512>;
473using h256s = std::vector<h256>;
474using h160s = std::vector<h160>;
475using h256Set = std::set<h256>;
476using h160Set = std::set<h160>;
477using h256Hash = std::unordered_set<h256>;
478using h160Hash = std::unordered_set<h160>;
479
481inline h160
482right160(h256 const& _t)
483{
484 h160 ret;
485 memcpy(ret.data(), _t.data() + 12, 20);
486 return ret;
487}
488
489} // 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:132
void randomize(Engine &_eng)
Populate with random data.
Definition FixedHash.h:232
bool contains(FixedHash const &_c) const
Definition FixedHash.h:184
FixedHash(bytesConstRef _b, ConstructFromHashType _t=FailIfDifferent)
Explicitly construct, copying from a byte array.
Definition FixedHash.h:99
bytesRef ref()
Definition FixedHash.h:204
bool containsBloom(FixedHash< M > const &_h)
Definition FixedHash.h:254
std::string hex() const
Definition FixedHash.h:201
bytes asBytes() const
Definition FixedHash.h:222
unsigned firstBitSet() const
Returns the index of the first bit set to one, or size() * 8 if no bits are set.
Definition FixedHash.h:282
FixedHash(unsigned _u)
Convert from unsigned.
Definition FixedHash.h:81
bytesConstRef ref() const
Definition FixedHash.h:207
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:176
std::array< uint8_t, N > const & asArray() const
Definition FixedHash.h:228
std::array< uint8_t, N > & asArray()
Definition FixedHash.h:225
bool operator==(FixedHash const &_c) const
Definition FixedHash.h:130
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:219
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:117
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:248
FixedHash< M > bloomPart() const
Definition FixedHash.h:260
uint8_t * data()
Definition FixedHash.h:210
FixedHash(uint8_t const *_bs, ConstructFromPointerType)
Explicitly construct, copying from a bytes in memory with given pointer.
Definition FixedHash.h:114
bool operator>=(FixedHash const &_c) const
Definition FixedHash.h:141
FixedHash & operator^=(FixedHash const &_c)
Definition FixedHash.h:146
FixedHash & operator&=(FixedHash const &_c)
Definition FixedHash.h:160
uint8_t operator[](unsigned _i) const
Definition FixedHash.h:189
uint8_t const * data() const
Definition FixedHash.h:213
FixedHash operator~() const
Definition FixedHash.h:167
auto begin() const -> typename std::array< uint8_t, N >::const_iterator
Definition FixedHash.h:216
uint8_t & operator[](unsigned _i)
Definition FixedHash.h:187
FixedHash operator^(FixedHash const &_c) const
Definition FixedHash.h:152
FixedHash operator|(FixedHash const &_c) const
Definition FixedHash.h:159
FixedHash & operator|=(FixedHash const &_c)
Definition FixedHash.h:153
std::string abridged() const
Definition FixedHash.h:192
bool operator!=(FixedHash const &_c) const
Definition FixedHash.h:131
std::string abridgedMiddle() const
Definition FixedHash.h:195
bool operator>(FixedHash const &_c) const
Definition FixedHash.h:143
static FixedHash random()
Definition FixedHash.h:239
FixedHash operator&(FixedHash const &_c) const
Definition FixedHash.h:166
bool operator<=(FixedHash const &_c) const
Definition FixedHash.h:142
SecureFixedHash operator&(SecureFixedHash const &_c) const
Definition FixedHash.h:428
SecureFixedHash operator^(SecureFixedHash const &_c) const
Definition FixedHash.h:416
SecureFixedHash & operator&=(SecureFixedHash const &_c)
Definition FixedHash.h:423
FixedHash< T > & writable()
Definition FixedHash.h:350
SecureFixedHash(SecureFixedHash< M > const &_h, ConstructFromHashType _t=FixedHash< T >::AlignLeft)
Definition FixedHash.h:325
static SecureFixedHash< T > random()
Definition FixedHash.h:441
bool operator>=(SecureFixedHash const &_c) const
Definition FixedHash.h:371
SecureFixedHash(SecureFixedHash< T > const &_h)
Definition FixedHash.h:321
bool operator>(SecureFixedHash const &_c) const
Definition FixedHash.h:379
SecureFixedHash(bytes const *_d, ConstructFromPointerType _t)
Definition FixedHash.h:333
bool operator<=(SecureFixedHash const &_c) const
Definition FixedHash.h:375
SecureFixedHash & operator^=(SecureFixedHash const &_c)
Definition FixedHash.h:411
SecureFixedHash(bytesConstRef _b, ConstructFromHashType _t=FixedHash< T >::FailIfDifferent)
Definition FixedHash.h:314
SecureFixedHash operator|(SecureFixedHash const &_c) const
Definition FixedHash.h:422
SecureFixedHash(FixedHash< M > const &_h, ConstructFromHashType _t=FixedHash< T >::AlignLeft)
Definition FixedHash.h:318
SecureFixedHash operator~() const
Definition FixedHash.h:429
SecureFixedHash operator&(FixedHash< T > const &_c) const
Definition FixedHash.h:409
typename FixedHash< T >::ConstructFromStringType ConstructFromStringType
Definition FixedHash.h:308
bool operator==(SecureFixedHash const &_c) const
Definition FixedHash.h:359
SecureFixedHash & operator^=(FixedHash< T > const &_c)
Definition FixedHash.h:392
SecureFixedHash()=default
SecureFixedHash< T > & operator=(SecureFixedHash< T > const &_c)
Definition FixedHash.h:338
bool operator<(SecureFixedHash const &_c) const
Definition FixedHash.h:367
SecureFixedHash & operator&=(FixedHash< T > const &_c)
Definition FixedHash.h:404
SecureFixedHash & operator|=(SecureFixedHash const &_c)
Definition FixedHash.h:417
SecureFixedHash(bytes const &_b, ConstructFromHashType _t=FixedHash< T >::FailIfDifferent)
Definition FixedHash.h:311
typename FixedHash< T >::ConstructFromHashType ConstructFromHashType
Definition FixedHash.h:307
typename FixedHash< T >::ConstructFromPointerType ConstructFromPointerType
Definition FixedHash.h:309
bytesConstRef ref() const
Definition FixedHash.h:438
FixedHash< T > const & makeInsecure() const
Definition FixedHash.h:349
SecureFixedHash(std::string const &_s, ConstructFromStringType _t=FixedHash< T >::FromHex, ConstructFromHashType _ht=FixedHash< T >::FailIfDifferent)
Definition FixedHash.h:328
SecureFixedHash & operator|=(FixedHash< T > const &_c)
Definition FixedHash.h:398
SecureFixedHash operator^(FixedHash< T > const &_c) const
Definition FixedHash.h:397
SecureFixedHash operator|(FixedHash< T > const &_c) const
Definition FixedHash.h:403
bool operator!=(SecureFixedHash const &_c) const
Definition FixedHash.h:363
uint8_t const * data() const
Definition FixedHash.h:439
A modifiable reference to an existing object or vector in memory.
Definition vector_ref.h:21
_T * data() const
Definition vector_ref.h:88
void cleanse()
Securely overwrite the memory.
Definition vector_ref.h:132
size_t size() const
Definition vector_ref.h:92
Definition Address.h:25
std::vector< h256 > h256s
Definition FixedHash.h:473
std::vector< h160 > h160s
Definition FixedHash.h:474
vector_ref< uint8_t const > bytesConstRef
std::vector< h512 > h512s
Definition FixedHash.h:472
std::set< h256 > h256Set
Definition FixedHash.h:475
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:478
WhenError
Definition CommonData.h:38
std::unordered_set< h256 > h256Hash
Definition FixedHash.h:477
std::set< h160 > h160Set
Definition FixedHash.h:476
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:482
Compile-time calculation of Log2 of constant values.
Definition FixedHash.h:39