5#ifndef DIGESTPP_PROVIDERS_BLAKE_HPP
6#define DIGESTPP_PROVIDERS_BLAKE_HPP
20namespace blake_functions
22 static inline void G(
int r,
int i, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d, uint32_t* M)
36 static inline void G(
int r,
int i, uint64_t& a, uint64_t& b, uint64_t& c, uint64_t& d, uint64_t* M)
51 static inline void round(
int r, T* M, T* v)
53 G(r, 0, v[0], v[4], v[8], v[12], M);
54 G(r, 1, v[1], v[5], v[9], v[13], M);
55 G(r, 2, v[2], v[6], v[10], v[14], M);
56 G(r, 3, v[3], v[7], v[11], v[15], M);
57 G(r, 4, v[0], v[5], v[10], v[15], M);
58 G(r, 5, v[1], v[6], v[11], v[12], M);
59 G(r, 6, v[2], v[7], v[8], v[13], M);
60 G(r, 7, v[3], v[4], v[9], v[14], M);
79 inline void transform(
const unsigned char* data,
size_t num_blks,
bool padding, std::array<T, 12>& H, uint64_t total,
bool final)
81 for (
size_t blk = 0; blk < num_blks; blk++)
84 for (
int i = 0; i < 16; i++)
85 M[i] =
byteswap(
reinterpret_cast<const T*
>(data)[blk * 16 + i]);
87 uint64_t totalbytes = total + (!
final ? (blk + 1) *
sizeof(M) * 8 : 0);
88 T t0 =
static_cast<T
>(totalbytes);
89 T t1 =
sizeof(T) == 8 ? 0 :
static_cast<T
>(totalbytes >> 32);
94 memcpy(v, H.data(),
sizeof(T) * 8);
95 v[8 + 0] = H[8] ^
C<T>(0);
96 v[8 + 1] = H[9] ^
C<T>(1);
97 v[8 + 2] = H[10] ^
C<T>(2);
98 v[8 + 3] = H[11] ^
C<T>(3);
100 v[13] = t0 ^
C<T>(5);
101 v[14] = t1 ^
C<T>(6);
102 v[15] = t1 ^
C<T>(7);
125 H[0] = H[0] ^ H[8] ^ v[0] ^ v[0 + 8];
126 H[0 + 4] = H[0 + 4] ^ H[8] ^ v[0 + 4] ^ v[0 + 8 + 4];
127 H[1] = H[1] ^ H[9] ^ v[1] ^ v[1 + 8];
128 H[1 + 4] = H[1 + 4] ^ H[9] ^ v[1 + 4] ^ v[1 + 8 + 4];
129 H[2] = H[2] ^ H[10] ^ v[2] ^ v[2 + 8];
130 H[2 + 4] = H[2 + 4] ^ H[10] ^ v[2 + 4] ^ v[2 + 8 + 4];
131 H[3] = H[3] ^ H[11] ^ v[3] ^ v[3 + 8];
132 H[3 + 4] = H[3 + 4] ^ H[11] ^ v[3 + 4] ^ v[3 + 8 + 4];
137 inline void set_salt(std::array<T, 12>& H,
const unsigned char* salt,
size_t saltlen)
140 for (
int i = 0; i < 4; i++)
141 H[8 + i] =
byteswap(
reinterpret_cast<const T*
>(salt)[i]);
143 H[8] = H[9] = H[10] = H[11] = 0;
147template<
size_t HS = 0>
153 template<size_t hss=HS, typename std::enable_if<hss == 0>::type* =
nullptr>
161 template<size_t hss=HS, typename std::enable_if<hss != 0>::type* =
nullptr>
165 static_assert(hss == 224 || hss == 256 || hss == 384 || hss == 512);
182 u.H512[0] = 0x6A09E667F3BCC908ull;
183 u.H512[1] = 0xBB67AE8584CAA73Bull;
184 u.H512[2] = 0x3C6EF372FE94F82Bull;
185 u.H512[3] = 0xA54FF53A5F1D36F1ull;
186 u.H512[4] = 0x510E527FADE682D1ull;
187 u.H512[5] = 0x9B05688C2B3E6C1Full;
188 u.H512[6] = 0x1F83D9ABFB41BD6Bull;
189 u.H512[7] = 0x5BE0CD19137E2179ull;
192 u.H512[0] = 0xcbbb9d5dc1059ed8ull;
193 u.H512[1] = 0x629a292a367cd507ull;
194 u.H512[2] = 0x9159015a3070dd17ull;
195 u.H512[3] = 0x152fecd8f70e5939ull;
196 u.H512[4] = 0x67332667ffc00b31ull;
197 u.H512[5] = 0x8eb44a8768581511ull;
198 u.H512[6] = 0xdb0c2e0d64f98fa7ull;
199 u.H512[7] = 0x47b5481dbefa4fa4ull;
202 u.H256[0] = 0x6a09e667;
203 u.H256[1] = 0xbb67ae85;
204 u.H256[2] = 0x3c6ef372;
205 u.H256[3] = 0xa54ff53a;
206 u.H256[4] = 0x510e527f;
207 u.H256[5] = 0x9b05688c;
208 u.H256[6] = 0x1f83d9ab;
209 u.H256[7] = 0x5be0cd19;
212 u.H256[0] = 0xC1059ED8;
213 u.H256[1] = 0x367CD507;
214 u.H256[2] = 0x3070DD17;
215 u.H256[3] = 0xF70E5939;
216 u.H256[4] = 0xFFC00B31;
217 u.H256[5] = 0x68581511;
218 u.H256[6] = 0x64F98FA7;
219 u.H256[7] = 0xBEFA4FA4;
224 inline void update(
const unsigned char* data,
size_t len)
227 [
this](
const unsigned char* data,
size_t len) { transform(data, len, false, false); });
230 inline void set_salt(
const unsigned char* salt,
size_t salt_len)
232 if (salt_len && ((hs > 256 && salt_len != 32) || (hs <= 256 && salt_len != 16)))
233 throw std::runtime_error(
"invalid salt length");
241 inline void final(
unsigned char*
hash)
243 size_t messageend = hs > 256 ? 111 : 55;
244 bool truncated = hs != 512 && hs != 256;
247 m[pos] = pos == messageend && !truncated ? 0x81 : 0x80;
248 if (pos++ > messageend)
250 if (block_bytes() != pos)
251 memset(&m[pos], 0, block_bytes() - pos);
252 transform(m.data(), 1,
false,
true);
256 if (pos <= messageend)
258 memset(&m[pos], 0, messageend - pos);
259 m[messageend] = truncated ? 0x00 : 0x01;
262 if (block_bytes() == 128)
263 memset(&m[128 - 16], 0,
sizeof(uint64_t));
264 memcpy(&m[block_bytes() - 8], &mlen,
sizeof(uint64_t));
265 transform(m.data(), 1, padding,
true);
268 for (
int i = 0; i < 8; i++)
274 for (
int i = 0; i < 8; i++)
289 inline size_t block_bytes()
const {
return hs > 256 ? 128 : 64; }
291 inline void transform(
const unsigned char* mp,
size_t num_blks,
bool padding,
bool final)
299 union { std::array<uint64_t, 12>
H512; std::array<uint32_t, 12>
H256; } u;
300 std::array<unsigned char, 128> m;
Definition blake_provider.hpp:149
blake_provider()
Definition blake_provider.hpp:162
blake_provider(size_t hashsize)
Definition blake_provider.hpp:154
~blake_provider()
Definition blake_provider.hpp:169
void update(const unsigned char *data, size_t len)
Definition blake_provider.hpp:224
void clear()
Definition blake_provider.hpp:280
void set_salt(const unsigned char *salt, size_t salt_len)
Definition blake_provider.hpp:230
std::array< uint32_t, 12 > H256
Definition blake_provider.hpp:299
std::array< uint64_t, 12 > H512
Definition blake_provider.hpp:299
size_t hash_size() const
Definition blake_provider.hpp:286
void init()
Definition blake_provider.hpp:174
static void G(int r, int i, uint32_t &a, uint32_t &b, uint32_t &c, uint32_t &d, uint32_t *M)
Definition blake_provider.hpp:22
uint64_t C< uint64_t >(int t)
Definition blake_provider.hpp:73
void set_salt(std::array< T, 12 > &H, const unsigned char *salt, size_t saltlen)
Definition blake_provider.hpp:137
uint32_t C< uint32_t >(int t)
Definition blake_provider.hpp:67
static void round(int r, T *M, T *v)
Definition blake_provider.hpp:51
void transform(const unsigned char *data, size_t num_blks, bool padding, std::array< T, 12 > &H, uint64_t total, bool final)
Definition blake_provider.hpp:79
uint16_t byteswap(uint16_t val)
Definition functions.hpp:16
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 blake_constants.hpp:16