digestpp 1.0
C++11 header-only message digest library
Loading...
Searching...
No Matches
groestl_provider.hpp
Go to the documentation of this file.
1/*
2This code is written by kerukuro and released into public domain.
3*/
4
5#ifndef DIGESTPP_PROVIDERS_GROESTL_HPP
6#define DIGESTPP_PROVIDERS_GROESTL_HPP
7
12#include <array>
13
14namespace digestpp
15{
16
17namespace detail
18{
19
20namespace groestl_functions
21{
22 template<int R>
23 static inline void roundP(uint64_t* x, uint64_t* y, uint64_t i)
24 {
25 for (int idx = 0; idx < R; idx++)
26 x[idx] ^= (static_cast<uint64_t>(idx) << 4) ^ i;
27
28 for (int c = R - 1; c >= 0; c--)
29 y[c] = groestl_constants<void>::T[0][static_cast<unsigned char>(x[(c + 0) % R])]
30 ^ groestl_constants<void>::T[1][static_cast<unsigned char>(x[(c + 1) % R] >> 8)]
31 ^ groestl_constants<void>::T[2][static_cast<unsigned char>(x[(c + 2) % R] >> 16)]
32 ^ groestl_constants<void>::T[3][static_cast<unsigned char>(x[(c + 3) % R] >> 24)]
33 ^ groestl_constants<void>::T[4][static_cast<unsigned char>(x[(c + 4) % R] >> 32)]
34 ^ groestl_constants<void>::T[5][static_cast<unsigned char>(x[(c + 5) % R] >> 40)]
35 ^ groestl_constants<void>::T[6][static_cast<unsigned char>(x[(c + 6) % R] >> 48)]
36 ^ groestl_constants<void>::T[7][static_cast<unsigned char>(x[(c + (R == 16 ? 11 : 7)) % R] >> 56)];
37 }
38
39 template<int R>
40 static inline void roundQ(uint64_t* x, uint64_t* y, uint64_t i)
41 {
42 for (int idx = 0; idx < R; idx++)
43 x[idx] ^= (0xffffffffffffffffull - (static_cast<uint64_t>(idx) << 60)) ^ i;
44
45 for (int c = R - 1; c >= 0; c--)
46 y[c] = groestl_constants<void>::T[0][static_cast<unsigned char>(x[(c + 1) % R])]
47 ^ groestl_constants<void>::T[1][static_cast<unsigned char>(x[(c + 3) % R] >> 8)]
48 ^ groestl_constants<void>::T[2][static_cast<unsigned char>(x[(c + 5) % R] >> 16)]
49 ^ groestl_constants<void>::T[3][static_cast<unsigned char>(x[(c + (R == 16 ? 11 : 7)) % R] >> 24)]
50 ^ groestl_constants<void>::T[4][static_cast<unsigned char>(x[(c + 0) % R] >> 32)]
51 ^ groestl_constants<void>::T[5][static_cast<unsigned char>(x[(c + 2) % R] >> 40)]
52 ^ groestl_constants<void>::T[6][static_cast<unsigned char>(x[(c + 4) % R] >> 48)]
53 ^ groestl_constants<void>::T[7][static_cast<unsigned char>(x[(c + 6) % R] >> 56)];
54 }
55
56 template<int R>
57 static inline void transform(uint64_t* h, const uint64_t* m)
58 {
59 uint64_t AQ1[R], AQ2[R], AP1[R], AP2[R];
60
61 for (int column = 0; column < R; column++)
62 {
63 AP1[column] = h[column] ^ m[column];
64 AQ1[column] = m[column];
65 }
66
67 for (uint64_t r = 0; r < (R == 16 ? 14 : 10); r += 2)
68 {
69 roundP<R>(AP1, AP2, r);
70 roundP<R>(AP2, AP1, r + 1);
71 roundQ<R>(AQ1, AQ2, r << 56);
72 roundQ<R>(AQ2, AQ1, (r + 1ull) << 56);
73 }
74
75 for (int column = 0; column < R; column++)
76 {
77 h[column] = AP1[column] ^ AQ1[column] ^ h[column];
78 }
79 }
80
81 template<int R>
82 static inline void outputTransform(uint64_t* h)
83 {
84 uint64_t t1[R];
85 uint64_t t2[R];
86
87 for (int column = 0; column < R; column++) {
88 t1[column] = h[column];
89 }
90
91 for (uint64_t r = 0; r < (R == 16 ? 14 : 10); r += 2) {
92 roundP<R>(t1, t2, r);
93 roundP<R>(t2, t1, r+1);
94 }
95
96 for (int column = 0; column < R; column++) {
97 h[column] ^= t1[column];
98 }
99 }
100
101}
102
103template<size_t HS = 0>
105{
106public:
107 static const bool is_xof = false;
108
109 template<size_t hss=HS, typename std::enable_if<hss == 0>::type* = nullptr>
110 groestl_provider(size_t hashsize)
111 : hs(hashsize)
112 {
113 validate_hash_size(hashsize, 512);
114 }
115
116 template<size_t hss=HS, typename std::enable_if<hss != 0>::type* = nullptr>
118 : hs(hss)
119 {
120 static_assert(hss <= 512 && hss > 0 && hss % 8 == 0);
121 }
122
124 {
125 clear();
126 }
127
128 inline void init()
129 {
130 pos = 0;
131 total = 0;
132 memset(&h[0], 0, sizeof(uint64_t)*16);
133 uint64_t hss = static_cast<uint64_t>(hash_size());
134 h[hss > 256 ? 15 : 7] = byteswap(hss);
135 }
136
137 inline void update(const unsigned char* data, size_t len)
138 {
139 detail::absorb_bytes(data, len, block_bytes(), block_bytes(), m.data(), pos, total,
140 [this](const unsigned char* data, size_t len) { transform(data, len); });
141 }
142
143 inline void final(unsigned char* hash)
144 {
145 m[pos++] = 0x80;
146 total += pos * 8;
147 size_t limit = block_bytes();
148 if (pos > limit - 8)
149 {
150 if (limit != pos)
151 memset(&m[pos], 0, limit - pos);
152 transform(m.data(), 1);
153 total += (block_bytes() - pos) * 8;
154 pos = 0;
155 }
156 memset(&m[pos], 0, limit - 8 - pos);
157 total += (block_bytes() - pos) * 8;
158 uint64_t mlen = byteswap(total / 8 / block_bytes());
159 memcpy(&m[limit - 8], &mlen, 64 / 8);
160 transform(m.data(), 1);
161 outputTransform();
162
163 const unsigned char* s = reinterpret_cast<const unsigned char*>(h.data());
164 for (size_t i = limit - hash_size() / 8, j = 0; i < limit; i++, j++) {
165 hash[j] = s[i];
166 }
167 }
168
169 inline void clear()
170 {
171 zero_memory(h);
172 zero_memory(m);
173 }
174
175 inline size_t hash_size() const { return hs; }
176
177private:
178 inline size_t block_bytes() const { return hs > 256 ? 128 : 64; }
179
180 inline void outputTransform()
181 {
182 if (hs > 256)
184 else
186 }
187
188 inline void transform(const unsigned char* mp, size_t num_blks)
189 {
190 for (size_t blk = 0; blk < num_blks; blk++)
191 {
192 if (hs > 256)
193 groestl_functions::transform<16>(&h[0], reinterpret_cast<const uint64_t*>(mp + block_bytes() * blk));
194 else
195 groestl_functions::transform<8>(&h[0], reinterpret_cast<const uint64_t*>(mp + block_bytes() * blk));
196 }
197 }
198
199 std::array<uint64_t, 16> h;
200 std::array<unsigned char, 128> m;
201 size_t hs;
202 size_t pos;
203 uint64_t total;
204
205};
206
207} // namespace detail
208
209} // namespace digestpp
210
211#endif
Definition groestl_provider.hpp:105
size_t hash_size() const
Definition groestl_provider.hpp:175
groestl_provider(size_t hashsize)
Definition groestl_provider.hpp:110
void clear()
Definition groestl_provider.hpp:169
void update(const unsigned char *data, size_t len)
Definition groestl_provider.hpp:137
~groestl_provider()
Definition groestl_provider.hpp:123
void init()
Definition groestl_provider.hpp:128
groestl_provider()
Definition groestl_provider.hpp:117
static void roundP(uint64_t *x, uint64_t *y, uint64_t i)
Definition groestl_provider.hpp:23
static void roundQ(uint64_t *x, uint64_t *y, uint64_t i)
Definition groestl_provider.hpp:40
static void transform(uint64_t *h, const uint64_t *m)
Definition groestl_provider.hpp:57
static void outputTransform(uint64_t *h)
Definition groestl_provider.hpp:82
uint16_t byteswap(uint16_t val)
Definition functions.hpp:16
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 groestl_constants.hpp:16
Definition traits.hpp:17