digestpp 1.0
C++11 header-only message digest library
Loading...
Searching...
No Matches
ascon_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_ASCON_HPP
6#define DIGESTPP_PROVIDERS_ASCON_HPP
7
12#include <array>
13
14namespace digestpp
15{
16
17namespace detail
18{
19
20template<ascon_type type>
22{
23public:
24 static const bool is_xof = type != ascon_type::hash;
25
27 : squeezing(false)
28 {
29 }
30
32 {
33 clear();
34 }
35
36 inline void init()
37 {
38 pos = 0;
39 total = 0;
40 squeezing = false;
41 zero_memory(H);
42 zero_memory(m);
43
44/*
45 Here is how the initial values are calculated:
46
47 if (type == ascon_type::cxof)
48 H[0] = 0x0000080000cc0004ull;
49 else if (type == ascon_type::xof)
50 H[0] = 0x0000080000cc0003ull;
51 else
52 {
53 H[0] = 0x0000080100cc0002ull;
54 uint16_t hs = 256; // theoretically can be different
55 memcpy(reinterpret_cast<unsigned char*>(&H[0]) + 3, &hs, sizeof(hs));
56 }
57 transform(m.data(), 1);
58*/
59
60 if (type == ascon_type::cxof)
62 else if (type == ascon_type::xof)
64 else
66
67 if (type == ascon_type::cxof)
68 {
69 uint64_t Z0 = Z.length() * 8;
70 update(reinterpret_cast<const unsigned char*>(&Z0), sizeof(Z0));
71 Z0 = 1ull;
72 if (!Z.empty())
73 update(reinterpret_cast<const unsigned char*>(Z.data()), Z.length());
74 size_t pad = Z.length() % 8;
75 update(reinterpret_cast<const unsigned char*>(&Z0), 8 - pad);
76 }
77 }
78
79 template<ascon_type t=type, typename std::enable_if<t == ascon_type::cxof>::type* = nullptr>
80 inline void set_customization(const std::string& customization)
81 {
82 Z = customization;
83 }
84
85 inline void update(const unsigned char* data, size_t len)
86 {
87 detail::absorb_bytes(data, len, 8, 8, m.data(), pos, total,
88 [this](const unsigned char* data, size_t len) { transform(data, len); });
89 }
90
91 inline void squeeze(unsigned char* hash, size_t hs)
92 {
93 size_t r = rate / 8;
94 size_t processed = 0;
95 if (!squeezing)
96 {
97 m[pos++] = '\x01';
98 if (r != pos)
99 memset(&m[pos], 0, r - pos);
100 transform(m.data(), 1);
101 memset(m.data(), 0, r);
102 squeezing = true;
103 }
104 else if (pos < r)
105 {
106 size_t to_copy = std::min(hs, r - pos);
107 memcpy(hash, reinterpret_cast<unsigned char*>(H.data()) + pos, to_copy);
108 processed += to_copy;
109 pos += to_copy;
110 }
111 else if (pos == r)
112 {
113 transform(m.data(), 1);
114 }
115
116 while (processed < hs)
117 {
118 if (processed)
119 transform(m.data(), 1);
120 pos = std::min(hs - processed, r);
121 memcpy(hash + processed, H.data(), pos);
122 processed += pos;
123 }
124 }
125
126 inline void final(unsigned char* hash)
127 {
128 return squeeze(hash, 256 / 8);
129 }
130
131 inline void clear()
132 {
133 zero_memory(H);
134 zero_memory(m);
135 }
136
137 inline size_t hash_size() const { return 256; }
138
139private:
140
141 inline void transform(const unsigned char* data, size_t num_blks)
142 {
143 for (size_t blk = 0; blk < num_blks; blk++)
144 {
145 H[0] ^= reinterpret_cast<const uint64_t*>(data)[blk];
146
147 for (int i = 0; i < 12; i++)
148 {
149 H[2] ^= ascon_constants<void>::RC[i];
150
151 H[0] ^= H[4];
152 H[4] ^= H[3];
153 H[2] ^= H[1];
154
155 uint64_t t0 = H[0] ^ (~H[1] & H[2]);
156 uint64_t t1 = H[1] ^ (~H[2] & H[3]);
157 uint64_t t2 = H[2] ^ (~H[3] & H[4]);
158 uint64_t t3 = H[3] ^ (~H[4] & H[0]);
159 uint64_t t4 = H[4] ^ (~H[0] & H[1]);
160
161 t1 ^= t0;
162 t0 ^= t4;
163 t3 ^= t2;
164 t2 = ~t2;
165
166 H[0] = t0 ^ rotate_right(t0, 19) ^ rotate_right(t0, 28);
167 H[1] = t1 ^ rotate_right(t1, 61) ^ rotate_right(t1, 39);
168 H[2] = t2 ^ rotate_right(t2, 1) ^ rotate_right(t2, 6);
169 H[3] = t3 ^ rotate_right(t3, 10) ^ rotate_right(t3, 17);
170 H[4] = t4 ^ rotate_right(t4, 7) ^ rotate_right(t4, 41);
171 }
172 }
173 }
174
175
176 std::array<uint64_t, 5> H;
177 std::array<unsigned char, 64> m;
178 std::string Z;
179 const size_t rate = 64;
180 size_t pos;
181 uint64_t total;
182 bool squeezing;
183};
184
185} // namespace detail
186
187} // namespace digestpp
188
189#endif
Definition ascon_provider.hpp:22
size_t hash_size() const
Definition ascon_provider.hpp:137
ascon_provider()
Definition ascon_provider.hpp:26
~ascon_provider()
Definition ascon_provider.hpp:31
void init()
Definition ascon_provider.hpp:36
void clear()
Definition ascon_provider.hpp:131
void update(const unsigned char *data, size_t len)
Definition ascon_provider.hpp:85
void set_customization(const std::string &customization)
Definition ascon_provider.hpp:80
void squeeze(unsigned char *hash, size_t hs)
Definition ascon_provider.hpp:91
uint32_t rotate_right(uint32_t x, unsigned n)
Definition functions.hpp:61
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 ascon_constants.hpp:16
Definition traits.hpp:17