-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathsha256.hpp
158 lines (129 loc) · 3.81 KB
/
sha256.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma once
#include <span>
#include <compare>
#include <fc/fwd.hpp>
#include <fc/string.hpp>
#include <fc/platform_independence.hpp>
#include <fc/io/raw_fwd.hpp>
#include <boost/functional/hash.hpp>
namespace fc
{
class sha256
{
public:
sha256();
explicit sha256( const std::string& hex_str );
explicit sha256( const char *data, size_t size );
std::string str()const;
operator std::string()const;
const char* data()const;
char* data();
size_t data_size() const { return 256 / 8; }
std::span<const uint8_t> to_uint8_span() const {
return {reinterpret_cast<const uint8_t*>(data()), reinterpret_cast<const uint8_t*>(data()) + data_size()};
}
bool empty()const {
return (_hash[0] | _hash[1] | _hash[2] | _hash[3]) == 0;
}
static sha256 hash( const char* d, uint32_t dlen );
static sha256 hash( const std::string& );
static sha256 hash( const sha256& );
template<typename T>
static sha256 hash( const T& t )
{
sha256::encoder e;
fc::raw::pack(e,t);
return e.result();
}
class encoder
{
public:
encoder();
~encoder();
void write( const char* d, uint32_t dlen );
void put( char c ) { write( &c, 1 ); }
void reset();
sha256 result();
private:
struct impl;
fc::fwd<impl,112> my;
};
template<typename T>
inline friend T& operator<<( T& ds, const sha256& ep ) {
ds.write( ep.data(), sizeof(ep) );
return ds;
}
template<typename T>
inline friend T& operator>>( T& ds, sha256& ep ) {
ds.read( ep.data(), sizeof(ep) );
return ds;
}
friend sha256 operator << ( const sha256& h1, uint32_t i );
friend sha256 operator >> ( const sha256& h1, uint32_t i );
friend sha256 operator ^ ( const sha256& h1, const sha256& h2 );
friend bool operator == ( const sha256& h1, const sha256& h2 );
friend std::strong_ordering operator <=> ( const sha256& h1, const sha256& h2 );
uint32_t pop_count()const
{
return (uint32_t)(__builtin_popcountll(_hash[0]) +
__builtin_popcountll(_hash[1]) +
__builtin_popcountll(_hash[2]) +
__builtin_popcountll(_hash[3]));
}
/**
* Count leading zero bits
*/
uint16_t clz()const;
/**
* Approximate (log_2(x) + 1) * 2**24.
*
* Detailed specs:
* - Return 0 when x == 0.
* - High 8 bits of result simply counts nonzero bits.
* - Low 24 bits of result are the 24 bits of input immediately after the most significant 1 in the input.
* - If above would require reading beyond the end of the input, zeros are used instead.
*/
uint32_t approx_log_32()const;
void set_to_inverse_approx_log_32( uint32_t x );
static double inverse_approx_log_32_double( uint32_t x );
uint64_t _hash[4];
};
typedef sha256 uint256;
class variant;
void to_variant( const sha256& bi, variant& v );
void from_variant( const variant& v, sha256& bi );
uint64_t hash64(const char* buf, size_t len);
} // fc
namespace std
{
template<>
struct hash<fc::sha256>
{
size_t operator()( const fc::sha256& s )const
{
return *((size_t*)&s);
}
};
inline std::ostream& operator<<(std::ostream& os, const fc::sha256& r) {
os << "sha256(" << r.str() << ")";
return os;
}
}
namespace boost
{
template<>
struct hash<fc::sha256>
{
size_t operator()( const fc::sha256& s )const
{
return s._hash[3];//*((size_t*)&s);
}
};
}
namespace fc {
inline size_t hash_value(const fc::sha256& s) {
return boost::hash<fc::sha256>()(s);
}
}
#include <fc/reflect/reflect.hpp>
FC_REFLECT_TYPENAME( fc::sha256 )