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