digestpp 1.0
C++11 header-only message digest library
Loading...
Searching...
No Matches
streebog_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_STREEBOG_HPP
6#define DIGESTPP_PROVIDERS_STREEBOG_HPP
7
12#include <array>
13
14namespace digestpp
15{
16
17namespace detail
18{
19
20namespace streebog_functions
21{
22 template<int I>
23 static inline uint64_t lps(unsigned char* ch)
24 {
25 return streebog_constants<void>::T[0][(ch[I])]
26 ^ streebog_constants<void>::T[1][(ch[8 + I])]
27 ^ streebog_constants<void>::T[2][(ch[16 + I])]
28 ^ streebog_constants<void>::T[3][(ch[24 + I])]
29 ^ streebog_constants<void>::T[4][(ch[32 + I])]
30 ^ streebog_constants<void>::T[5][(ch[40 + I])]
31 ^ streebog_constants<void>::T[6][(ch[48 + I])]
32 ^ streebog_constants<void>::T[7][(ch[56 + I])];
33 }
34
35 static inline void lps_block(uint64_t* block)
36 {
37 unsigned char ch[64];
38 memcpy(ch, block, 64);
39
40 block[0] = lps<0>(ch);
41 block[1] = lps<1>(ch);
42 block[2] = lps<2>(ch);
43 block[3] = lps<3>(ch);
44 block[4] = lps<4>(ch);
45 block[5] = lps<5>(ch);
46 block[6] = lps<6>(ch);
47 block[7] = lps<7>(ch);
48 }
49
50 static inline void xor_blocks(uint64_t* block, const uint64_t* toxor)
51 {
52 block[0] ^= toxor[0];
53 block[1] ^= toxor[1];
54 block[2] ^= toxor[2];
55 block[3] ^= toxor[3];
56 block[4] ^= toxor[4];
57 block[5] ^= toxor[5];
58 block[6] ^= toxor[6];
59 block[7] ^= toxor[7];
60 }
61
62 static inline void e(uint64_t* K, const unsigned char* m)
63 {
64 uint64_t tmp[8];
65 memcpy(tmp, K, 64);
66 xor_blocks(K, reinterpret_cast<const uint64_t*>(m));
67 for (int i = 0; i < 12; i++)
68 {
69 lps_block(K);
71 lps_block(tmp);
72 xor_blocks(K, tmp);
73 }
74 }
75
76 static inline void gN(uint64_t* h, const unsigned char* m, uint64_t N)
77 {
78 uint64_t hN[8];
79 memcpy(hN, h, 64);
80 hN[0] ^= N;
81 lps_block(hN);
82 e(hN, m);
83 xor_blocks(h, hN);
84 xor_blocks(h, reinterpret_cast<const uint64_t*>(m));
85 }
86
87 static inline void addm(const unsigned char* m, uint64_t* h)
88 {
89 const uint64_t* m64 = reinterpret_cast<const uint64_t*>(m);
90 bool carry = false, overflow = false;
91 for (int i = 0; i < 8; i++)
92 {
93 uint64_t t = h[i] + m64[i];
94 overflow = t < h[i] || t < m64[i];
95 h[i] = t + carry;
96 carry = overflow;
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 streebog_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], hs == 512 ? 0 : 1, sizeof(uint64_t) * 8);
132 memset(&S[0], 0, sizeof(uint64_t) * 8);
133 }
134
135 inline void update(const unsigned char* data, size_t len)
136 {
137 detail::absorb_bytes(data, len, 64, 64, m.data(), pos, total,
138 [this](const unsigned char* data, size_t len) { transform(data, len, false); });
139 }
140
141 inline void final(unsigned char* hash)
142 {
143 m[pos++] = 0x01;
144 if (pos != 64)
145 memset(&m[pos], 0, 64 - pos);
146 transform(&m[0], 1, false);
147 total += (pos - 1) * 8;
148
149 memcpy(&m[0], &total, sizeof(total));
150 memset(&m[sizeof(total)], 0, 64 - sizeof(total));
151 transform(&m[0], 1, true);
152 transform(reinterpret_cast<const unsigned char*>(&S[0]), 1, true);
153
154 memcpy(hash, &h[8 - hash_size()/64], hash_size() / 8);
155 }
156
157 inline void clear()
158 {
159 zero_memory(h);
160 zero_memory(S);
161 zero_memory(m);
162 }
163
164 inline size_t hash_size() const { return hs; }
165
166private:
167 inline void transform(const unsigned char* mp, size_t num_blks, bool final)
168 {
169 for (size_t blk = 0; blk < num_blks; blk++)
170 {
171 streebog_functions::gN(&h[0], mp + blk * 64, final ? 0ULL : total + blk * 512);
172
173 if (!final)
174 streebog_functions::addm(mp + blk * 64, &S[0]);
175 }
176 }
177
178 std::array<uint64_t, 8> h;
179 std::array<uint64_t, 8> S;
180 std::array<unsigned char, 64> m;
181 size_t hs;
182 size_t pos;
183 uint64_t total;
184
185};
186
187} // namespace detail
188
189} // namespace digestpp
190
191#endif
Definition streebog_provider.hpp:104
void update(const unsigned char *data, size_t len)
Definition streebog_provider.hpp:135
size_t hash_size() const
Definition streebog_provider.hpp:164
streebog_provider()
Definition streebog_provider.hpp:116
streebog_provider(size_t hashsize)
Definition streebog_provider.hpp:109
void init()
Definition streebog_provider.hpp:127
~streebog_provider()
Definition streebog_provider.hpp:122
void clear()
Definition streebog_provider.hpp:157
static void addm(const unsigned char *m, uint64_t *h)
Definition streebog_provider.hpp:87
static void e(uint64_t *K, const unsigned char *m)
Definition streebog_provider.hpp:62
static uint64_t lps(unsigned char *ch)
Definition streebog_provider.hpp:23
static void lps_block(uint64_t *block)
Definition streebog_provider.hpp:35
static void xor_blocks(uint64_t *block, const uint64_t *toxor)
Definition streebog_provider.hpp:50
static void gN(uint64_t *h, const unsigned char *m, uint64_t N)
Definition streebog_provider.hpp:76
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 streebog_constants.hpp:16