75 template<size_t hss=HS, typename std::enable_if<hss == 0>::type* =
nullptr>
79 static_assert(
sizeof(T) == 4 ||
sizeof(T) == 8,
"LSH only supports 4 and 8 bits word size");
83 template<size_t hss=HS, typename std::enable_if<hss != 0>::type* =
nullptr>
87 static_assert(
sizeof(T) == 4 ||
sizeof(T) == 8,
"LSH only supports 4 and 8 bits word size");
88 static_assert(hss <= N && hss > 0 && hss % 8 == 0);
103 memset(&cv[2], 0,
sizeof(T) * 14);
104 unsigned char msg[N / 2];
105 memset(msg, 0,
sizeof(msg));
108 memset(&t[0], 0,
sizeof(T) * 16);
109 memset(&msgexp, 0,
sizeof(msgexp));
112 inline void update(
const unsigned char* data,
size_t len)
115 [
this](
const unsigned char* data,
size_t len) { transform(data, len); });
118 inline void final(
unsigned char*
hash)
122 if (pos != block_bytes())
123 memset(&m[pos], 0, block_bytes() - pos);
124 transform(m.data(), 1);
127 for (
size_t i = 0; i < 8; ++i)
128 h[i] = cv[i] ^ cv[i + 8];
143 inline size_t block_bytes()
const {
return N / 2; }
145 inline void msgexpand(
const unsigned char* mp)
147 memcpy(msgexp.data(), mp, block_bytes());
148 for (
size_t i = 2; i < NS + 1; i++)
150 msgexp[i][0] = msgexp[i - 1][0] + msgexp[i - 2][3];
151 msgexp[i][1] = msgexp[i - 1][1] + msgexp[i - 2][2];
152 msgexp[i][2] = msgexp[i - 1][2] + msgexp[i - 2][0];
153 msgexp[i][3] = msgexp[i - 1][3] + msgexp[i - 2][1];
154 msgexp[i][4] = msgexp[i - 1][4] + msgexp[i - 2][7];
155 msgexp[i][5] = msgexp[i - 1][5] + msgexp[i - 2][4];
156 msgexp[i][6] = msgexp[i - 1][6] + msgexp[i - 2][5];
157 msgexp[i][7] = msgexp[i - 1][7] + msgexp[i - 2][6];
158 msgexp[i][8] = msgexp[i - 1][8] + msgexp[i - 2][11];
159 msgexp[i][9] = msgexp[i - 1][9] + msgexp[i - 2][10];
160 msgexp[i][10] = msgexp[i - 1][10] + msgexp[i - 2][8];
161 msgexp[i][11] = msgexp[i - 1][11] + msgexp[i - 2][9];
162 msgexp[i][12] = msgexp[i - 1][12] + msgexp[i - 2][15];
163 msgexp[i][13] = msgexp[i - 1][13] + msgexp[i - 2][12];
164 msgexp[i][14] = msgexp[i - 1][14] + msgexp[i - 2][13];
165 msgexp[i][15] = msgexp[i - 1][15] + msgexp[i - 2][14];
169 inline void addmix(
size_t l,
size_t i, T sc,
int alpha,
int beta,
int gamma)
171 T x = cv[l] ^ msgexp[i][l];
172 T y = cv[l + 8] ^ msgexp[i][l + 8];
179 inline void step(
size_t i,
int alpha,
int beta)
207 inline void transform(
const unsigned char* mp,
size_t num_blks)
209 for (
size_t blk = 0; blk < num_blks; blk++)
211 msgexpand(mp + block_bytes() * blk);
212 for (
size_t i = 0; i < NS; i += 2)
217 for (
size_t i = 0; i < 16; ++i)
218 cv[i] ^= msgexp[NS][i];
222 constexpr static size_t N =
sizeof(T) == 4 ? 256 : 512;
223 constexpr static size_t NS =
sizeof(T) == 4 ? 26 : 28;
225 std::array<T, 16> cv;
227 std::array<std::array<T, 16>, NS + 1> msgexp;
228 std::array<
unsigned char, N / 2> m;
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