5#ifndef DIGESTPP_PROVIDERS_BLAKE2_HPP
6#define DIGESTPP_PROVIDERS_BLAKE2_HPP
21namespace blake2_functions
23 static inline void G(
int r,
int i, uint64_t& a, uint64_t& b, uint64_t& c, uint64_t& d, uint64_t* M)
35 static inline void G(
int r,
int i, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d, uint32_t* M)
48 static inline void round(
int r, T* M, T* v)
50 G(r, 0, v[0], v[4], v[8], v[12], M);
51 G(r, 1, v[1], v[5], v[9], v[13], M);
52 G(r, 2, v[2], v[6], v[10], v[14], M);
53 G(r, 3, v[3], v[7], v[11], v[15], M);
54 G(r, 4, v[0], v[5], v[10], v[15], M);
55 G(r, 5, v[1], v[6], v[11], v[12], M);
56 G(r, 6, v[2], v[7], v[8], v[13], M);
57 G(r, 7, v[3], v[4], v[9], v[14], M);
75 inline void initH(std::array<uint32_t, 8>& H, uint8_t fanout)
79 H[0] ^= 0x01010000ULL;
82 inline void initH(std::array<uint64_t, 8>& H, uint8_t fanout)
86 H[0] ^= 0x0000000001010000ULL;
89 inline void initX(std::array<uint32_t, 8>& H,
size_t hs,
size_t processed,
size_t xoffset, uint32_t rhs)
92 H[0] ^= (rhs == std::numeric_limits<uint32_t>::max() ?
static_cast<size_t>(32) : std::min(hs - processed,
static_cast<size_t>(32)));
96 H[3] ^=
static_cast<uint16_t
>(rhs);
99 inline void initX(std::array<uint64_t, 8>& H,
size_t hs,
size_t processed,
size_t xoffset, uint64_t rhs)
102 H[0] ^= (rhs == std::numeric_limits<uint64_t>::max() ?
static_cast<size_t>(64) : std::min(hs - processed,
static_cast<size_t>(64)));
103 H[0] ^= 0x0000004000000000ULL;
106 H[2] ^= 0x0000000000004000ULL;
111template<
typename T, blake2_type type,
size_t HS>
112class blake2p_provider;
114template<
typename T, blake2_type type,
size_t HS = 0>
120 template<size_t hss=HS, typename std::enable_if<hss == 0>::type* =
nullptr>
122 : hs(hashsize), squeezing(false)
124 static_assert(
sizeof(T) == 8 ||
sizeof(T) == 4,
"Invalid T size");
138 template<size_t hss=HS, typename std::enable_if<hss != 0>::type* =
nullptr>
140 : hs(hss), squeezing(false)
142 static_assert(
sizeof(T) == 8 ||
sizeof(T) == 4,
"Invalid T size");
145 static_assert(hss <= limit && hss > 0 && hss % 8 == 0);
173 T rhs = type ==
blake2_type::x_hash ?
static_cast<T
>(hs/8) : (
static_cast<T
>(-1) >> (
sizeof(T) * 4));
175 H[1] ^= (rhs << (N / 16));
179 H[0] ^= (k.size() << 8);
187 H[0] ^=
static_cast<T
>(fanout) << 16 |
static_cast<T
>(2) << 24;
188 H[
sizeof(T) == 8 ? 1 : 2] ^=
static_cast<T
>(nodeoffset);
191 H[2] ^=
static_cast<T
>(nodedepth) | (
static_cast<T
>(N / 8) << 8);
193 H[3] ^=
static_cast<T
>(nodedepth) << 16 |
static_cast<T
>(N / 8) << 24;
196 if (!fanout || !nodedepth)
200 inline void update(
const unsigned char* data,
size_t len)
203 [
this](
const unsigned char* data,
size_t len) { transform(data, len, false); });
208 if (key.length() > N / 8)
209 throw std::runtime_error(
"invalid key length");
214 inline void set_salt(
const unsigned char* salt,
size_t salt_len)
216 if (salt_len && salt_len != N / 32)
217 throw std::runtime_error(
"invalid salt length");
219 memcpy(&s[0], salt, salt_len);
224 if (personalization_len && personalization_len != N / 32)
225 throw std::runtime_error(
"invalid personalization length");
227 memcpy(&p[0], personalization, personalization_len);
239 size_t processed = 0;
247 memset(&m[pos], 0, N / 4 - pos);
248 transform(m.data(), 1,
true);
249 memcpy(&m[0], H.data(), N / 8);
251 else if (pos < N / 8)
253 size_t to_copy = std::min(hs, N / 8 - pos);
254 memcpy(
hash,
reinterpret_cast<unsigned char*
>(H.data()) + pos, to_copy);
255 processed += to_copy;
258 while (processed < hs)
266 memset(&m[N / 8], 0, m.size() - N / 8);
267 transform(m.data(), 1,
true);
268 pos = std::min(hs - processed, N / 8);
269 memcpy(
hash + processed, H.data(), pos);
274 inline void final(
unsigned char*
hash,
size_t hs_override = 0)
277 size_t hss = hs_override ? hs_override : hs;
281 memset(&m[pos], 0, N / 4 - pos);
282 transform(m.data(), 1,
true);
283 memcpy(
hash, H.data(), hss / 8);
305 inline void absorb_key()
310 unsigned char key[N / 4];
311 memcpy(key, k.data(), k.length());
312 if (k.length() != N / 4)
313 memset(key + k.length(), 0, N / 4 - k.length());
317 inline void transform(
const unsigned char* data,
size_t num_blks,
bool padding)
319 for (
size_t blk = 0; blk < num_blks; blk++)
322 for (
int i = 0; i < 16; i++)
323 M[i] =
reinterpret_cast<const T*
>(data)[blk * 16 + i];
324 uint64_t totalbytes = total / 8 + (padding ? 0 : (blk + 1) * N) / 4;
325 T t0 =
static_cast<T
>(totalbytes);
326 T t1 = N == 512 ? 0 :
static_cast<T
>(totalbytes >> 32);
331 f0 =
static_cast<T
>(-1);
332 f1 = fanout && (nodeoffset == fanout - 1 || nodedepth) ?
static_cast<T
>(-1) : 0;
336 memcpy(v, H.data(),
sizeof(T) * 8);
362 H[0] = H[0] ^ v[0] ^ v[0 + 8];
363 H[0 + 4] = H[0 + 4] ^ v[0 + 4] ^ v[0 + 8 + 4];
364 H[1] = H[1] ^ v[1] ^ v[1 + 8];
365 H[1 + 4] = H[1 + 4] ^ v[1 + 4] ^ v[1 + 8 + 4];
366 H[2] = H[2] ^ v[2] ^ v[2 + 8];
367 H[2 + 4] = H[2 + 4] ^ v[2 + 4] ^ v[2 + 8 + 4];
368 H[3] = H[3] ^ v[3] ^ v[3 + 8];
369 H[3 + 4] = H[3 + 4] ^ v[3 + 4] ^ v[3 + 8 + 4];
376 constexpr static size_t N =
sizeof(T) == 8 ? 512 : 256;
381 std::array<
unsigned char, N / 4> m;
Definition blake2_provider.hpp:116
void set_salt(const unsigned char *salt, size_t salt_len)
Definition blake2_provider.hpp:214
void squeeze(unsigned char *hash, size_t hs)
Definition blake2_provider.hpp:237
blake2_provider()
Definition blake2_provider.hpp:139
void set_key(const std::string &key)
Definition blake2_provider.hpp:206
void init()
Definition blake2_provider.hpp:159
blake2_provider(size_t hashsize=N)
Definition blake2_provider.hpp:121
void update(const unsigned char *data, size_t len)
Definition blake2_provider.hpp:200
void set_blake2p_params(uint8_t fo, uint8_t nd, uint8_t no)
Definition blake2_provider.hpp:230
~blake2_provider()
Definition blake2_provider.hpp:154
size_t hash_size() const
Definition blake2_provider.hpp:302
void clear()
Definition blake2_provider.hpp:289
void set_personalization(const unsigned char *personalization, size_t personalization_len)
Definition blake2_provider.hpp:222
Definition blake2p_provider.hpp:23
void initH(std::array< uint32_t, 8 > &H, uint8_t fanout)
Definition blake2_provider.hpp:75
static void round(int r, T *M, T *v)
Definition blake2_provider.hpp:48
uint64_t IV< uint64_t >(int t)
Definition blake2_provider.hpp:70
uint32_t IV< uint32_t >(int t)
Definition blake2_provider.hpp:64
void initX(std::array< uint32_t, 8 > &H, size_t hs, size_t processed, size_t xoffset, uint32_t rhs)
Definition blake2_provider.hpp:89
static void G(int r, int i, uint64_t &a, uint64_t &b, uint64_t &c, uint64_t &d, uint64_t *M)
Definition blake2_provider.hpp:23
uint32_t rotate_right(uint32_t x, unsigned n)
Definition functions.hpp:61
void validate_hash_size(size_t hs, std::initializer_list< size_t > set)
Definition validate_hash_size.hpp:14
void zero_memory(void *v, size_t n)
Definition functions.hpp:85
void absorb_bytes(const unsigned char *data, size_t len, size_t bs, size_t bschk, unsigned char *m, size_t &pos, T &total, TF transform)
Definition absorb_data.hpp:16
digestpp namespace
Definition ascon.hpp:14
Definition blake2_constants.hpp:39
Definition blake2_constants.hpp:16
Definition blake2_constants.hpp:28