45using digest_t = std::array< std::uint32_t, digest_array_size >;
51 return static_cast< std::uint8_t
>( what );
58 return static_cast< std::uint32_t
>( what );
65 return reinterpret_cast< const std::uint8_t *
>( what );
68template<
unsigned int Shift >
72 return (x << Shift) | (x >> (32 - Shift));
75template<
unsigned int Shift >
79 return ::restinio::utils::impl::bitops::n_bits_from< std::uint8_t, Shift >(x);
82static uint32_t blk(
const int_block_t & block,
const size_t i)
84 return rotate_left<1>(
85 block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i] );
89R0(
const int_block_t & block,
const uint32_t v, uint32_t &w,
const uint32_t x,
const uint32_t y, uint32_t &z,
const size_t i)
91 z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rotate_left<5>( v );
92 w = rotate_left<30>( w );
97R1(
int_block_t & block,
const uint32_t v, uint32_t &w,
const uint32_t x,
const uint32_t y, uint32_t &z,
const size_t i)
99 block[i] = blk(block, i);
100 z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rotate_left<5>(v);
101 w = rotate_left<30>(w);
106R2(
int_block_t & block,
const uint32_t v, uint32_t &w,
const uint32_t x,
const uint32_t y, uint32_t &z,
const size_t i)
108 block[i] = blk(block, i);
109 z += (w^x^y) + block[i] + 0x6ed9eba1 + rotate_left<5>(v);
110 w = rotate_left<30>(w);
114R3(
int_block_t & block,
const uint32_t v, uint32_t &w,
const uint32_t x,
const uint32_t y, uint32_t &z,
const size_t i)
116 block[i] = blk(block, i);
117 z += (((w|x)&y)|(w&x)) + block[i] + 0x8f1bbcdc + rotate_left<5>(v);
118 w = rotate_left<30>(w);
123R4(
int_block_t & block,
const uint32_t v, uint32_t &w,
const uint32_t x,
const uint32_t y, uint32_t &z,
const size_t i)
125 block[i] = blk(block, i);
126 z += (w^x^y) + block[i] + 0xca62c1d6 + rotate_left<5>(v);
127 w = rotate_left<30>(w);
144 std::uint32_t a = digest[0];
145 std::uint32_t b = digest[1];
146 std::uint32_t c = digest[2];
147 std::uint32_t d = digest[3];
148 std::uint32_t e = digest[4];
150 R0(block, a, b, c, d, e, 0);
151 R0(block, e, a, b, c, d, 1);
152 R0(block, d, e, a, b, c, 2);
153 R0(block, c, d, e, a, b, 3);
154 R0(block, b, c, d, e, a, 4);
155 R0(block, a, b, c, d, e, 5);
156 R0(block, e, a, b, c, d, 6);
157 R0(block, d, e, a, b, c, 7);
158 R0(block, c, d, e, a, b, 8);
159 R0(block, b, c, d, e, a, 9);
160 R0(block, a, b, c, d, e, 10);
161 R0(block, e, a, b, c, d, 11);
162 R0(block, d, e, a, b, c, 12);
163 R0(block, c, d, e, a, b, 13);
164 R0(block, b, c, d, e, a, 14);
165 R0(block, a, b, c, d, e, 15);
166 R1(block, e, a, b, c, d, 0);
167 R1(block, d, e, a, b, c, 1);
168 R1(block, c, d, e, a, b, 2);
169 R1(block, b, c, d, e, a, 3);
170 R2(block, a, b, c, d, e, 4);
171 R2(block, e, a, b, c, d, 5);
172 R2(block, d, e, a, b, c, 6);
173 R2(block, c, d, e, a, b, 7);
174 R2(block, b, c, d, e, a, 8);
175 R2(block, a, b, c, d, e, 9);
176 R2(block, e, a, b, c, d, 10);
177 R2(block, d, e, a, b, c, 11);
178 R2(block, c, d, e, a, b, 12);
179 R2(block, b, c, d, e, a, 13);
180 R2(block, a, b, c, d, e, 14);
181 R2(block, e, a, b, c, d, 15);
182 R2(block, d, e, a, b, c, 0);
183 R2(block, c, d, e, a, b, 1);
184 R2(block, b, c, d, e, a, 2);
185 R2(block, a, b, c, d, e, 3);
186 R2(block, e, a, b, c, d, 4);
187 R2(block, d, e, a, b, c, 5);
188 R2(block, c, d, e, a, b, 6);
189 R2(block, b, c, d, e, a, 7);
190 R3(block, a, b, c, d, e, 8);
191 R3(block, e, a, b, c, d, 9);
192 R3(block, d, e, a, b, c, 10);
193 R3(block, c, d, e, a, b, 11);
194 R3(block, b, c, d, e, a, 12);
195 R3(block, a, b, c, d, e, 13);
196 R3(block, e, a, b, c, d, 14);
197 R3(block, d, e, a, b, c, 15);
198 R3(block, c, d, e, a, b, 0);
199 R3(block, b, c, d, e, a, 1);
200 R3(block, a, b, c, d, e, 2);
201 R3(block, e, a, b, c, d, 3);
202 R3(block, d, e, a, b, c, 4);
203 R3(block, c, d, e, a, b, 5);
204 R3(block, b, c, d, e, a, 6);
205 R3(block, a, b, c, d, e, 7);
206 R3(block, e, a, b, c, d, 8);
207 R3(block, d, e, a, b, c, 9);
208 R3(block, c, d, e, a, b, 10);
209 R3(block, b, c, d, e, a, 11);
210 R4(block, a, b, c, d, e, 12);
211 R4(block, e, a, b, c, d, 13);
212 R4(block, d, e, a, b, c, 14);
213 R4(block, c, d, e, a, b, 15);
214 R4(block, b, c, d, e, a, 0);
215 R4(block, a, b, c, d, e, 1);
216 R4(block, e, a, b, c, d, 2);
217 R4(block, d, e, a, b, c, 3);
218 R4(block, c, d, e, a, b, 4);
219 R4(block, b, c, d, e, a, 5);
220 R4(block, a, b, c, d, e, 6);
221 R4(block, e, a, b, c, d, 7);
222 R4(block, d, e, a, b, c, 8);
223 R4(block, c, d, e, a, b, 9);
224 R4(block, b, c, d, e, a, 10);
225 R4(block, a, b, c, d, e, 11);
226 R4(block, e, a, b, c, d, 12);
227 R4(block, d, e, a, b, c, 13);
228 R4(block, c, d, e, a, b, 14);
229 R4(block, b, c, d, e, a, 15);
254 update(
const std::uint8_t * what, std::size_t length )
301 const auto push_uint_to_buffer = [&](
auto big_value ) {
302 const auto v =
static_cast<std::uint32_t
>(big_value);
303 m_buffer[ i++ ] = octet_from<24>(v);
304 m_buffer[ i++ ] = octet_from<16>(v);
308 push_uint_to_buffer( total_bits >> 32 );
309 push_uint_to_buffer( total_bits & 0xffffffffu );
356template<
unsigned int Shift >
360 return ::restinio::utils::impl::bitops::n_bits_from< unsigned int, Shift, 4 >(v);
363template<
unsigned int Shift >
367 return ::restinio::utils::impl::bitops::n_bits_from< unsigned int, Shift, 8 >(v);
375 using namespace details;
377 static const char digits[] =
"0123456789abcdef";
382 for(
const auto c : what )
384 result += digits[halfbyte<28>(c)];
385 result += digits[halfbyte<24>(c)];
386 result += digits[halfbyte<20>(c)];
387 result += digits[halfbyte<16>(c)];
388 result += digits[halfbyte<12>(c)];
389 result += digits[halfbyte<8>(c)];
390 result += digits[halfbyte<4>(c)];
391 result += digits[halfbyte<0>(c)];
400 using namespace details;
405 for(
const auto c : what )
407 result.push_back(
static_cast<char>(byte<24>(c)) );
408 result.push_back(
static_cast<char>(byte<16>(c)) );
409 result.push_back(
static_cast<char>(byte<8>(c)) );
410 result.push_back(
static_cast<char>(byte<0>(c)) );
426 const std::uint8_t *
const start =
as_uint8_ptr( begin );
427 const std::uint8_t *
const finish =
as_uint8_ptr( end );
428 const auto length =
static_cast< std::size_t
>( finish - start );
unsigned int halfbyte(digest_t::value_type v)
unsigned int byte(digest_t::value_type v)
constexpr std::uint8_t block_size
std::array< std::uint32_t, digest_array_size > digest_t
std::array< std::uint32_t, block_ints > int_block_t
std::uint8_t as_uint8(T what)
std::array< std::uint8_t, block_size > byte_block_t
std::uint32_t as_uint32(T what)
void R4(int_block_t &block, const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
std::string to_string(const digest_t &what)
void R1(int_block_t &block, const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
void R2(int_block_t &block, const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
std::uint8_t octet_from(std::uint32_t x)
std::string to_hex_string(const digest_t &what)
constexpr std::uint8_t block_ints
constexpr std::size_t digest_array_size
void R0(const int_block_t &block, const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
digest_t make_digest(const std::uint8_t *what, std::size_t length)
const std::uint8_t * as_uint8_ptr(const T *what)
void transform(digest_t &digest, const byte_block_t &buf)
constexpr std::uint8_t digest_size
std::uint32_t rotate_left(const std::uint32_t x)
constexpr std::uint8_t word_size
void R3(int_block_t &block, const uint32_t v, uint32_t &w, const uint32_t x, const uint32_t y, uint32_t &z, const size_t i)
nonstd::string_view string_view_t
void store_total_bits_to_buffer()
size_t m_transforms_count
builder_t & update(const std::uint8_t *what, std::size_t length)
std::uint_fast64_t calculate_total_bits_count() const