Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/lsh256.cpp
Line
Count
Source (jump to first uncovered line)
1
// lsh.cpp - written and placed in the public domain by Jeffrey Walton
2
//           Based on the specification and source code provided by
3
//           Korea Internet & Security Agency (KISA) website. Also
4
//           see https://seed.kisa.or.kr/kisa/algorithm/EgovLSHInfo.do
5
//           and https://seed.kisa.or.kr/kisa/Board/22/detailView.do.
6
7
// We are hitting some sort of GCC bug in the LSH AVX2 code path.
8
// Clang is OK on the AVX2 code path. We believe it is GCC Issue
9
// 82735, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82735. It
10
// makes using zeroupper a little tricky.
11
12
#include "pch.h"
13
#include "config.h"
14
15
#include "lsh.h"
16
#include "cpu.h"
17
#include "misc.h"
18
19
ANONYMOUS_NAMESPACE_BEGIN
20
21
/* LSH Constants */
22
23
const unsigned int LSH256_MSG_BLK_BYTE_LEN = 128;
24
// const unsigned int LSH256_MSG_BLK_BIT_LEN = 1024;
25
// const unsigned int LSH256_CV_BYTE_LEN = 64;
26
const unsigned int LSH256_HASH_VAL_MAX_BYTE_LEN = 32;
27
28
// const unsigned int MSG_BLK_WORD_LEN = 32;
29
const unsigned int CV_WORD_LEN = 16;
30
const unsigned int CONST_WORD_LEN = 8;
31
const unsigned int HASH_VAL_MAX_WORD_LEN = 8;
32
// const unsigned int WORD_BIT_LEN = 32;
33
const unsigned int NUM_STEPS = 26;
34
35
const unsigned int ROT_EVEN_ALPHA = 29;
36
const unsigned int ROT_EVEN_BETA = 1;
37
const unsigned int ROT_ODD_ALPHA = 5;
38
const unsigned int ROT_ODD_BETA = 17;
39
40
const unsigned int LSH_TYPE_256_256 = 0x0000020;
41
const unsigned int LSH_TYPE_256_224 = 0x000001C;
42
43
// const unsigned int LSH_TYPE_224 = LSH_TYPE_256_224;
44
// const unsigned int LSH_TYPE_256 = LSH_TYPE_256_256;
45
46
/* Error Code */
47
48
const unsigned int LSH_SUCCESS = 0x0;
49
// const unsigned int LSH_ERR_NULL_PTR = 0x2401;
50
// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402;
51
const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403;
52
const unsigned int LSH_ERR_INVALID_STATE = 0x2404;
53
54
/* Index into our state array */
55
56
const unsigned int AlgorithmType = 80;
57
const unsigned int RemainingBits = 81;
58
59
NAMESPACE_END
60
61
NAMESPACE_BEGIN(CryptoPP)
62
NAMESPACE_BEGIN(LSH)
63
64
/* -------------------------------------------------------- *
65
* LSH: iv
66
* -------------------------------------------------------- */
67
68
//extern const word32 LSH256_IV224[CV_WORD_LEN];
69
//extern const word32 LSH256_IV256[CV_WORD_LEN];
70
//extern const word32 LSH256_StepConstants[CONST_WORD_LEN * NUM_STEPS];
71
72
CRYPTOPP_ALIGN_DATA(32)
73
extern
74
const word32 LSH256_IV224[CV_WORD_LEN] = {
75
  0x068608D3, 0x62D8F7A7, 0xD76652AB, 0x4C600A43, 0xBDC40AA8, 0x1ECA0B68, 0xDA1A89BE, 0x3147D354,
76
  0x707EB4F9, 0xF65B3862, 0x6B0B2ABE, 0x56B8EC0A, 0xCF237286, 0xEE0D1727, 0x33636595, 0x8BB8D05F
77
};
78
79
CRYPTOPP_ALIGN_DATA(32)
80
extern
81
const word32 LSH256_IV256[CV_WORD_LEN] = {
82
  0x46a10f1f, 0xfddce486, 0xb41443a8, 0x198e6b9d, 0x3304388d, 0xb0f5a3c7, 0xb36061c4, 0x7adbd553,
83
  0x105d5378, 0x2f74de54, 0x5c2f2d95, 0xf2553fbe, 0x8051357a, 0x138668c8, 0x47aa4484, 0xe01afb41
84
};
85
86
/* -------------------------------------------------------- *
87
* LSH: step constants
88
* -------------------------------------------------------- */
89
90
extern
91
const word32 LSH256_StepConstants[CONST_WORD_LEN * NUM_STEPS] = {
92
  0x917caf90, 0x6c1b10a2, 0x6f352943, 0xcf778243, 0x2ceb7472, 0x29e96ff2, 0x8a9ba428, 0x2eeb2642,
93
  0x0e2c4021, 0x872bb30e, 0xa45e6cb2, 0x46f9c612, 0x185fe69e, 0x1359621b, 0x263fccb2, 0x1a116870,
94
  0x3a6c612f, 0xb2dec195, 0x02cb1f56, 0x40bfd858, 0x784684b6, 0x6cbb7d2e, 0x660c7ed8, 0x2b79d88a,
95
  0xa6cd9069, 0x91a05747, 0xcdea7558, 0x00983098, 0xbecb3b2e, 0x2838ab9a, 0x728b573e, 0xa55262b5,
96
  0x745dfa0f, 0x31f79ed8, 0xb85fce25, 0x98c8c898, 0x8a0669ec, 0x60e445c2, 0xfde295b0, 0xf7b5185a,
97
  0xd2580983, 0x29967709, 0x182df3dd, 0x61916130, 0x90705676, 0x452a0822, 0xe07846ad, 0xaccd7351,
98
  0x2a618d55, 0xc00d8032, 0x4621d0f5, 0xf2f29191, 0x00c6cd06, 0x6f322a67, 0x58bef48d, 0x7a40c4fd,
99
  0x8beee27f, 0xcd8db2f2, 0x67f2c63b, 0xe5842383, 0xc793d306, 0xa15c91d6, 0x17b381e5, 0xbb05c277,
100
  0x7ad1620a, 0x5b40a5bf, 0x5ab901a2, 0x69a7a768, 0x5b66d9cd, 0xfdee6877, 0xcb3566fc, 0xc0c83a32,
101
  0x4c336c84, 0x9be6651a, 0x13baa3fc, 0x114f0fd1, 0xc240a728, 0xec56e074, 0x009c63c7, 0x89026cf2,
102
  0x7f9ff0d0, 0x824b7fb5, 0xce5ea00f, 0x605ee0e2, 0x02e7cfea, 0x43375560, 0x9d002ac7, 0x8b6f5f7b,
103
  0x1f90c14f, 0xcdcb3537, 0x2cfeafdd, 0xbf3fc342, 0xeab7b9ec, 0x7a8cb5a3, 0x9d2af264, 0xfacedb06,
104
  0xb052106e, 0x99006d04, 0x2bae8d09, 0xff030601, 0xa271a6d6, 0x0742591d, 0xc81d5701, 0xc9a9e200,
105
  0x02627f1e, 0x996d719d, 0xda3b9634, 0x02090800, 0x14187d78, 0x499b7624, 0xe57458c9, 0x738be2c9,
106
  0x64e19d20, 0x06df0f36, 0x15d1cb0e, 0x0b110802, 0x2c95f58c, 0xe5119a6d, 0x59cd22ae, 0xff6eac3c,
107
  0x467ebd84, 0xe5ee453c, 0xe79cd923, 0x1c190a0d, 0xc28b81b8, 0xf6ac0852, 0x26efd107, 0x6e1ae93b,
108
  0xc53c41ca, 0xd4338221, 0x8475fd0a, 0x35231729, 0x4e0d3a7a, 0xa2b45b48, 0x16c0d82d, 0x890424a9,
109
  0x017e0c8f, 0x07b5a3f5, 0xfa73078e, 0x583a405e, 0x5b47b4c8, 0x570fa3ea, 0xd7990543, 0x8d28ce32,
110
  0x7f8a9b90, 0xbd5998fc, 0x6d7a9688, 0x927a9eb6, 0xa2fc7d23, 0x66b38e41, 0x709e491a, 0xb5f700bf,
111
  0x0a262c0f, 0x16f295b9, 0xe8111ef5, 0x0d195548, 0x9f79a0c5, 0x1a41cfa7, 0x0ee7638a, 0xacf7c074,
112
  0x30523b19, 0x09884ecf, 0xf93014dd, 0x266e9d55, 0x191a6664, 0x5c1176c1, 0xf64aed98, 0xa4b83520,
113
  0x828d5449, 0x91d71dd8, 0x2944f2d6, 0x950bf27b, 0x3380ca7d, 0x6d88381d, 0x4138868e, 0x5ced55c4,
114
  0x0fe19dcb, 0x68f4f669, 0x6e37c8ff, 0xa0fe6e10, 0xb44b47b0, 0xf5c0558a, 0x79bf14cf, 0x4a431a20,
115
  0xf17f68da, 0x5deb5fd1, 0xa600c86d, 0x9f6c7eb0, 0xff92f864, 0xb615e07f, 0x38d3e448, 0x8d5d3a6a,
116
  0x70e843cb, 0x494b312e, 0xa6c93613, 0x0beb2f4f, 0x928b5d63, 0xcbf66035, 0x0cb82c80, 0xea97a4f7,
117
  0x592c0f3b, 0x947c5f77, 0x6fff49b9, 0xf71a7e5a, 0x1de8c0f5, 0xc2569600, 0xc4e4ac8c, 0x823c9ce1
118
};
119
120
NAMESPACE_END  // LSH
121
NAMESPACE_END  // Crypto++
122
123
ANONYMOUS_NAMESPACE_BEGIN
124
125
using CryptoPP::byte;
126
using CryptoPP::word32;
127
using CryptoPP::rotlFixed;
128
using CryptoPP::rotlConstant;
129
130
using CryptoPP::GetBlock;
131
using CryptoPP::LittleEndian;
132
using CryptoPP::ConditionalByteReverse;
133
using CryptoPP::LITTLE_ENDIAN_ORDER;
134
135
using CryptoPP::LSH::LSH256_IV224;
136
using CryptoPP::LSH::LSH256_IV256;
137
using CryptoPP::LSH::LSH256_StepConstants;
138
139
typedef byte lsh_u8;
140
typedef word32 lsh_u32;
141
typedef word32 lsh_uint;
142
typedef word32 lsh_err;
143
typedef word32 lsh_type;
144
145
struct LSH256_Context
146
{
147
  LSH256_Context(word32* state, word32 algType, word32& remainingBitLength) :
148
    cv_l(state+0), cv_r(state+8), sub_msgs(state+16),
149
    last_block(reinterpret_cast<byte*>(state+48)),
150
    remain_databitlen(remainingBitLength),
151
0
    alg_type(static_cast<lsh_type>(algType)) {}
152
153
  lsh_u32* cv_l;  // start of our state block
154
  lsh_u32* cv_r;
155
  lsh_u32* sub_msgs;
156
  lsh_u8*  last_block;
157
  lsh_u32& remain_databitlen;
158
  lsh_type alg_type;
159
};
160
161
struct LSH256_Internal
162
{
163
  LSH256_Internal(word32* state) :
164
    submsg_e_l(state+16), submsg_e_r(state+24),
165
0
    submsg_o_l(state+32), submsg_o_r(state+40) { }
166
167
  lsh_u32* submsg_e_l; /* even left sub-message  */
168
  lsh_u32* submsg_e_r; /* even right sub-message */
169
  lsh_u32* submsg_o_l; /* odd left sub-message   */
170
  lsh_u32* submsg_o_r; /* odd right sub-message  */
171
};
172
173
const word32 g_gamma256[8] = { 0, 8, 16, 24, 24, 16, 8, 0 };
174
175
/* LSH AlgType Macro */
176
177
0
inline bool LSH_IS_LSH512(lsh_uint val) {
178
0
  return (val & 0xf0000) == 0;
179
0
}
180
181
0
inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) {
182
0
  return val >> 24;
183
0
}
184
185
0
inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) {
186
0
  return val & 0xffff;
187
0
}
188
189
0
inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) {
190
0
  return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val);
191
0
}
192
193
0
inline lsh_u32 loadLE32(lsh_u32 v) {
194
0
  return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v);
195
0
}
196
197
0
lsh_u32 ROTL(lsh_u32 x, lsh_u32 r) {
198
0
  return rotlFixed(x, r);
199
0
}
200
201
// Original code relied upon unaligned lsh_u32 buffer
202
inline void load_msg_blk(LSH256_Internal* i_state, const lsh_u8 msgblk[LSH256_MSG_BLK_BYTE_LEN])
203
0
{
204
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
205
206
0
  lsh_u32* submsg_e_l = i_state->submsg_e_l;
207
0
  lsh_u32* submsg_e_r = i_state->submsg_e_r;
208
0
  lsh_u32* submsg_o_l = i_state->submsg_o_l;
209
0
  lsh_u32* submsg_o_r = i_state->submsg_o_r;
210
211
0
  typedef GetBlock<word32, LittleEndian, false> InBlock;
212
213
0
  InBlock input(msgblk);
214
0
  input(submsg_e_l[0])(submsg_e_l[1])(submsg_e_l[2])(submsg_e_l[3])
215
0
    (submsg_e_l[4])(submsg_e_l[5])(submsg_e_l[6])(submsg_e_l[7])
216
0
    (submsg_e_r[0])(submsg_e_r[1])(submsg_e_r[2])(submsg_e_r[3])
217
0
    (submsg_e_r[4])(submsg_e_r[5])(submsg_e_r[6])(submsg_e_r[7])
218
0
    (submsg_o_l[0])(submsg_o_l[1])(submsg_o_l[2])(submsg_o_l[3])
219
0
    (submsg_o_l[4])(submsg_o_l[5])(submsg_o_l[6])(submsg_o_l[7])
220
0
    (submsg_o_r[0])(submsg_o_r[1])(submsg_o_r[2])(submsg_o_r[3])
221
0
    (submsg_o_r[4])(submsg_o_r[5])(submsg_o_r[6])(submsg_o_r[7]);
222
0
}
223
224
inline void msg_exp_even(LSH256_Internal* i_state)
225
0
{
226
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
227
228
0
  lsh_u32* submsg_e_l = i_state->submsg_e_l;
229
0
  lsh_u32* submsg_e_r = i_state->submsg_e_r;
230
0
  lsh_u32* submsg_o_l = i_state->submsg_o_l;
231
0
  lsh_u32* submsg_o_r = i_state->submsg_o_r;
232
233
0
  lsh_u32 temp;
234
0
  temp = submsg_e_l[0];
235
0
  submsg_e_l[0] = submsg_o_l[0] + submsg_e_l[3];
236
0
  submsg_e_l[3] = submsg_o_l[3] + submsg_e_l[1];
237
0
  submsg_e_l[1] = submsg_o_l[1] + submsg_e_l[2];
238
0
  submsg_e_l[2] = submsg_o_l[2] + temp;
239
0
  temp = submsg_e_l[4];
240
0
  submsg_e_l[4] = submsg_o_l[4] + submsg_e_l[7];
241
0
  submsg_e_l[7] = submsg_o_l[7] + submsg_e_l[6];
242
0
  submsg_e_l[6] = submsg_o_l[6] + submsg_e_l[5];
243
0
  submsg_e_l[5] = submsg_o_l[5] + temp;
244
0
  temp = submsg_e_r[0];
245
0
  submsg_e_r[0] = submsg_o_r[0] + submsg_e_r[3];
246
0
  submsg_e_r[3] = submsg_o_r[3] + submsg_e_r[1];
247
0
  submsg_e_r[1] = submsg_o_r[1] + submsg_e_r[2];
248
0
  submsg_e_r[2] = submsg_o_r[2] + temp;
249
0
  temp = submsg_e_r[4];
250
0
  submsg_e_r[4] = submsg_o_r[4] + submsg_e_r[7];
251
0
  submsg_e_r[7] = submsg_o_r[7] + submsg_e_r[6];
252
0
  submsg_e_r[6] = submsg_o_r[6] + submsg_e_r[5];
253
0
  submsg_e_r[5] = submsg_o_r[5] + temp;
254
0
}
255
256
inline void msg_exp_odd(LSH256_Internal* i_state)
257
0
{
258
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
259
260
0
  lsh_u32* submsg_e_l = i_state->submsg_e_l;
261
0
  lsh_u32* submsg_e_r = i_state->submsg_e_r;
262
0
  lsh_u32* submsg_o_l = i_state->submsg_o_l;
263
0
  lsh_u32* submsg_o_r = i_state->submsg_o_r;
264
265
0
  lsh_u32 temp;
266
0
  temp = submsg_o_l[0];
267
0
  submsg_o_l[0] = submsg_e_l[0] + submsg_o_l[3];
268
0
  submsg_o_l[3] = submsg_e_l[3] + submsg_o_l[1];
269
0
  submsg_o_l[1] = submsg_e_l[1] + submsg_o_l[2];
270
0
  submsg_o_l[2] = submsg_e_l[2] + temp;
271
0
  temp = submsg_o_l[4];
272
0
  submsg_o_l[4] = submsg_e_l[4] + submsg_o_l[7];
273
0
  submsg_o_l[7] = submsg_e_l[7] + submsg_o_l[6];
274
0
  submsg_o_l[6] = submsg_e_l[6] + submsg_o_l[5];
275
0
  submsg_o_l[5] = submsg_e_l[5] + temp;
276
0
  temp = submsg_o_r[0];
277
0
  submsg_o_r[0] = submsg_e_r[0] + submsg_o_r[3];
278
0
  submsg_o_r[3] = submsg_e_r[3] + submsg_o_r[1];
279
0
  submsg_o_r[1] = submsg_e_r[1] + submsg_o_r[2];
280
0
  submsg_o_r[2] = submsg_e_r[2] + temp;
281
0
  temp = submsg_o_r[4];
282
0
  submsg_o_r[4] = submsg_e_r[4] + submsg_o_r[7];
283
0
  submsg_o_r[7] = submsg_e_r[7] + submsg_o_r[6];
284
0
  submsg_o_r[6] = submsg_e_r[6] + submsg_o_r[5];
285
0
  submsg_o_r[5] = submsg_e_r[5] + temp;
286
0
}
287
288
inline void load_sc(const lsh_u32** p_const_v, size_t i)
289
0
{
290
0
  CRYPTOPP_ASSERT(p_const_v != NULLPTR);
291
292
0
  *p_const_v = &LSH256_StepConstants[i];
293
0
}
294
295
inline void msg_add_even(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_Internal* i_state)
296
0
{
297
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
298
299
0
  lsh_u32* submsg_e_l = i_state->submsg_e_l;
300
0
  lsh_u32* submsg_e_r = i_state->submsg_e_r;
301
302
0
  cv_l[0] ^= submsg_e_l[0];  cv_l[1] ^= submsg_e_l[1];
303
0
  cv_l[2] ^= submsg_e_l[2];  cv_l[3] ^= submsg_e_l[3];
304
0
  cv_l[4] ^= submsg_e_l[4];  cv_l[5] ^= submsg_e_l[5];
305
0
  cv_l[6] ^= submsg_e_l[6];  cv_l[7] ^= submsg_e_l[7];
306
0
  cv_r[0] ^= submsg_e_r[0];  cv_r[1] ^= submsg_e_r[1];
307
0
  cv_r[2] ^= submsg_e_r[2];  cv_r[3] ^= submsg_e_r[3];
308
0
  cv_r[4] ^= submsg_e_r[4];  cv_r[5] ^= submsg_e_r[5];
309
0
  cv_r[6] ^= submsg_e_r[6];  cv_r[7] ^= submsg_e_r[7];
310
0
}
311
312
inline void msg_add_odd(lsh_u32 cv_l[8], lsh_u32 cv_r[8], LSH256_Internal* i_state)
313
0
{
314
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
315
316
0
  lsh_u32* submsg_o_l = i_state->submsg_o_l;
317
0
  lsh_u32* submsg_o_r = i_state->submsg_o_r;
318
319
0
  cv_l[0] ^= submsg_o_l[0];  cv_l[1] ^= submsg_o_l[1];
320
0
  cv_l[2] ^= submsg_o_l[2];  cv_l[3] ^= submsg_o_l[3];
321
0
  cv_l[4] ^= submsg_o_l[4];  cv_l[5] ^= submsg_o_l[5];
322
0
  cv_l[6] ^= submsg_o_l[6];  cv_l[7] ^= submsg_o_l[7];
323
0
  cv_r[0] ^= submsg_o_r[0];  cv_r[1] ^= submsg_o_r[1];
324
0
  cv_r[2] ^= submsg_o_r[2];  cv_r[3] ^= submsg_o_r[3];
325
0
  cv_r[4] ^= submsg_o_r[4];  cv_r[5] ^= submsg_o_r[5];
326
0
  cv_r[6] ^= submsg_o_r[6];  cv_r[7] ^= submsg_o_r[7];
327
0
}
328
329
inline void add_blk(lsh_u32 cv_l[8], lsh_u32 cv_r[8])
330
0
{
331
0
  cv_l[0] += cv_r[0];
332
0
  cv_l[1] += cv_r[1];
333
0
  cv_l[2] += cv_r[2];
334
0
  cv_l[3] += cv_r[3];
335
0
  cv_l[4] += cv_r[4];
336
0
  cv_l[5] += cv_r[5];
337
0
  cv_l[6] += cv_r[6];
338
0
  cv_l[7] += cv_r[7];
339
0
}
340
341
template <unsigned int R>
342
inline void rotate_blk(lsh_u32 cv[8])
343
0
{
344
0
  cv[0] = rotlConstant<R>(cv[0]);
345
0
  cv[1] = rotlConstant<R>(cv[1]);
346
0
  cv[2] = rotlConstant<R>(cv[2]);
347
0
  cv[3] = rotlConstant<R>(cv[3]);
348
0
  cv[4] = rotlConstant<R>(cv[4]);
349
0
  cv[5] = rotlConstant<R>(cv[5]);
350
0
  cv[6] = rotlConstant<R>(cv[6]);
351
0
  cv[7] = rotlConstant<R>(cv[7]);
352
0
}
Unexecuted instantiation: lsh256.cpp:void (anonymous namespace)::rotate_blk<29u>(unsigned int*)
Unexecuted instantiation: lsh256.cpp:void (anonymous namespace)::rotate_blk<1u>(unsigned int*)
Unexecuted instantiation: lsh256.cpp:void (anonymous namespace)::rotate_blk<5u>(unsigned int*)
Unexecuted instantiation: lsh256.cpp:void (anonymous namespace)::rotate_blk<17u>(unsigned int*)
353
354
inline void xor_with_const(lsh_u32 cv_l[8], const lsh_u32 const_v[8])
355
0
{
356
0
  cv_l[0] ^= const_v[0];
357
0
  cv_l[1] ^= const_v[1];
358
0
  cv_l[2] ^= const_v[2];
359
0
  cv_l[3] ^= const_v[3];
360
0
  cv_l[4] ^= const_v[4];
361
0
  cv_l[5] ^= const_v[5];
362
0
  cv_l[6] ^= const_v[6];
363
0
  cv_l[7] ^= const_v[7];
364
0
}
365
366
inline void rotate_msg_gamma(lsh_u32 cv_r[8])
367
0
{
368
0
  cv_r[1] = rotlFixed(cv_r[1], g_gamma256[1]);
369
0
  cv_r[2] = rotlFixed(cv_r[2], g_gamma256[2]);
370
0
  cv_r[3] = rotlFixed(cv_r[3], g_gamma256[3]);
371
0
  cv_r[4] = rotlFixed(cv_r[4], g_gamma256[4]);
372
0
  cv_r[5] = rotlFixed(cv_r[5], g_gamma256[5]);
373
0
  cv_r[6] = rotlFixed(cv_r[6], g_gamma256[6]);
374
0
}
375
376
inline void word_perm(lsh_u32 cv_l[8], lsh_u32 cv_r[8])
377
0
{
378
0
  lsh_u32 temp;
379
0
  temp = cv_l[0];
380
0
  cv_l[0] = cv_l[6];
381
0
  cv_l[6] = cv_r[6];
382
0
  cv_r[6] = cv_r[2];
383
0
  cv_r[2] = cv_l[1];
384
0
  cv_l[1] = cv_l[4];
385
0
  cv_l[4] = cv_r[4];
386
0
  cv_r[4] = cv_r[0];
387
0
  cv_r[0] = cv_l[2];
388
0
  cv_l[2] = cv_l[5];
389
0
  cv_l[5] = cv_r[7];
390
0
  cv_r[7] = cv_r[1];
391
0
  cv_r[1] = temp;
392
0
  temp = cv_l[3];
393
0
  cv_l[3] = cv_l[7];
394
0
  cv_l[7] = cv_r[5];
395
0
  cv_r[5] = cv_r[3];
396
0
  cv_r[3] = temp;
397
0
}
398
399
/* -------------------------------------------------------- *
400
* step function
401
* -------------------------------------------------------- */
402
403
template <unsigned int Alpha, unsigned int Beta>
404
inline void mix(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 const_v[8])
405
0
{
406
0
  add_blk(cv_l, cv_r);
407
0
  rotate_blk<Alpha>(cv_l);
408
0
  xor_with_const(cv_l, const_v);
409
0
  add_blk(cv_r, cv_l);
410
0
  rotate_blk<Beta>(cv_r);
411
0
  add_blk(cv_l, cv_r);
412
0
  rotate_msg_gamma(cv_r);
413
0
}
Unexecuted instantiation: lsh256.cpp:void (anonymous namespace)::mix<29u, 1u>(unsigned int*, unsigned int*, unsigned int const*)
Unexecuted instantiation: lsh256.cpp:void (anonymous namespace)::mix<5u, 17u>(unsigned int*, unsigned int*, unsigned int const*)
414
415
/* -------------------------------------------------------- *
416
* compression function
417
* -------------------------------------------------------- */
418
419
inline void compress(LSH256_Context* ctx, const lsh_u8 pdMsgBlk[LSH256_MSG_BLK_BYTE_LEN])
420
0
{
421
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
422
423
0
  LSH256_Internal  s_state(ctx->cv_l);
424
0
  LSH256_Internal* i_state = &s_state;
425
426
0
  const lsh_u32* const_v = NULL;
427
0
  lsh_u32* cv_l = ctx->cv_l;
428
0
  lsh_u32* cv_r = ctx->cv_r;
429
430
0
  load_msg_blk(i_state, pdMsgBlk);
431
432
0
  msg_add_even(cv_l, cv_r, i_state);
433
0
  load_sc(&const_v, 0);
434
0
  mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
435
0
  word_perm(cv_l, cv_r);
436
437
0
  msg_add_odd(cv_l, cv_r, i_state);
438
0
  load_sc(&const_v, 8);
439
0
  mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
440
0
  word_perm(cv_l, cv_r);
441
442
0
  for (size_t i = 1; i < NUM_STEPS / 2; i++)
443
0
  {
444
0
    msg_exp_even(i_state);
445
0
    msg_add_even(cv_l, cv_r, i_state);
446
0
    load_sc(&const_v, 16 * i);
447
0
    mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
448
0
    word_perm(cv_l, cv_r);
449
450
0
    msg_exp_odd(i_state);
451
0
    msg_add_odd(cv_l, cv_r, i_state);
452
0
    load_sc(&const_v, 16 * i + 8);
453
0
    mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
454
0
    word_perm(cv_l, cv_r);
455
0
  }
456
457
0
  msg_exp_even(i_state);
458
0
  msg_add_even(cv_l, cv_r, i_state);
459
0
}
460
461
/* -------------------------------------------------------- */
462
463
inline void load_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8], const lsh_u32 iv[16])
464
0
{
465
0
  cv_l[0] = iv[0];
466
0
  cv_l[1] = iv[1];
467
0
  cv_l[2] = iv[2];
468
0
  cv_l[3] = iv[3];
469
0
  cv_l[4] = iv[4];
470
0
  cv_l[5] = iv[5];
471
0
  cv_l[6] = iv[6];
472
0
  cv_l[7] = iv[7];
473
0
  cv_r[0] = iv[8];
474
0
  cv_r[1] = iv[9];
475
0
  cv_r[2] = iv[10];
476
0
  cv_r[3] = iv[11];
477
0
  cv_r[4] = iv[12];
478
0
  cv_r[5] = iv[13];
479
0
  cv_r[6] = iv[14];
480
0
  cv_r[7] = iv[15];
481
0
}
482
483
inline void zero_iv(lsh_u32 cv_l[8], lsh_u32 cv_r[8])
484
0
{
485
0
  std::memset(cv_l, 0x00, 8*sizeof(lsh_u32));
486
0
  std::memset(cv_r, 0x00, 8*sizeof(lsh_u32));
487
0
}
488
489
inline void zero_submsgs(LSH256_Context* ctx)
490
0
{
491
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
492
493
0
  lsh_u32* sub_msgs = ctx->sub_msgs;
494
0
  std::memset(sub_msgs, 0x00, 32*sizeof(lsh_u32));
495
0
}
496
497
inline void init224(LSH256_Context* ctx)
498
0
{
499
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
500
501
0
  zero_submsgs(ctx);
502
0
  load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV224);
503
0
}
504
505
inline void init256(LSH256_Context* ctx)
506
0
{
507
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
508
509
0
  zero_submsgs(ctx);
510
0
  load_iv(ctx->cv_l, ctx->cv_r, LSH256_IV256);
511
0
}
512
513
/* -------------------------------------------------------- */
514
515
inline void fin(LSH256_Context* ctx)
516
0
{
517
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
518
519
0
  for (size_t i = 0; i < HASH_VAL_MAX_WORD_LEN; i++){
520
0
    ctx->cv_l[i] = loadLE32(ctx->cv_l[i] ^ ctx->cv_r[i]);
521
0
  }
522
0
}
523
524
/* -------------------------------------------------------- */
525
526
inline void get_hash(LSH256_Context* ctx, lsh_u8* pbHashVal)
527
0
{
528
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
529
0
  CRYPTOPP_ASSERT(ctx->alg_type != 0);
530
0
  CRYPTOPP_ASSERT(pbHashVal != NULLPTR);
531
532
0
  lsh_uint alg_type = ctx->alg_type;
533
0
  lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type);
534
0
  lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type);
535
536
  // Multiplying by looks odd...
537
0
  std::memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len);
538
0
  if (hash_val_bit_len){
539
0
    pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len);
540
0
  }
541
0
}
542
543
/* -------------------------------------------------------- */
544
545
lsh_err lsh256_init(LSH256_Context* ctx)
546
0
{
547
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
548
0
  CRYPTOPP_ASSERT(ctx->alg_type != 0);
549
550
0
  lsh_u32 alg_type = ctx->alg_type;
551
0
  const lsh_u32* const_v = NULL;
552
0
  ctx->remain_databitlen = 0;
553
554
0
  switch (alg_type)
555
0
  {
556
0
  case LSH_TYPE_256_256:
557
0
    init256(ctx);
558
0
    return LSH_SUCCESS;
559
0
  case LSH_TYPE_256_224:
560
0
    init224(ctx);
561
0
    return LSH_SUCCESS;
562
0
  default:
563
0
    break;
564
0
  }
565
566
0
  lsh_u32* cv_l = ctx->cv_l;
567
0
  lsh_u32* cv_r = ctx->cv_r;
568
569
0
  zero_iv(cv_l, cv_r);
570
0
  cv_l[0] = LSH256_HASH_VAL_MAX_BYTE_LEN;
571
0
  cv_l[1] = LSH_GET_HASHBIT(alg_type);
572
573
0
  for (size_t i = 0; i < NUM_STEPS / 2; i++)
574
0
  {
575
    //Mix
576
0
    load_sc(&const_v, i * 16);
577
0
    mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
578
0
    word_perm(cv_l, cv_r);
579
580
0
    load_sc(&const_v, i * 16 + 8);
581
0
    mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
582
0
    word_perm(cv_l, cv_r);
583
0
  }
584
585
0
  return LSH_SUCCESS;
586
0
}
587
588
lsh_err lsh256_update(LSH256_Context* ctx, const lsh_u8* data, size_t databitlen)
589
0
{
590
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
591
0
  CRYPTOPP_ASSERT(data != NULLPTR);
592
0
  CRYPTOPP_ASSERT(databitlen % 8 == 0);
593
0
  CRYPTOPP_ASSERT(ctx->alg_type != 0);
594
595
0
  if (databitlen == 0){
596
0
    return LSH_SUCCESS;
597
0
  }
598
599
  // We are byte oriented. tail bits will always be 0.
600
0
  size_t databytelen = databitlen >> 3;
601
  // lsh_uint pos2 = databitlen & 0x7;
602
0
  const size_t pos2 = 0;
603
604
0
  size_t remain_msg_byte = ctx->remain_databitlen >> 3;
605
  // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7;
606
0
  const size_t remain_msg_bit = 0;
607
608
0
  if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){
609
0
    return LSH_ERR_INVALID_STATE;
610
0
  }
611
0
  if (remain_msg_bit > 0){
612
0
    return LSH_ERR_INVALID_DATABITLEN;
613
0
  }
614
615
0
  if (databytelen + remain_msg_byte < LSH256_MSG_BLK_BYTE_LEN)
616
0
  {
617
0
    std::memcpy(ctx->last_block + remain_msg_byte, data, databytelen);
618
0
    ctx->remain_databitlen += (lsh_uint)databitlen;
619
0
    remain_msg_byte += (lsh_uint)databytelen;
620
0
    if (pos2){
621
0
      ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff);
622
0
    }
623
0
    return LSH_SUCCESS;
624
0
  }
625
626
0
  if (remain_msg_byte > 0){
627
0
    size_t more_byte = LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte;
628
0
    std::memcpy(ctx->last_block + remain_msg_byte, data, more_byte);
629
0
    compress(ctx, ctx->last_block);
630
0
    data += more_byte;
631
0
    databytelen -= more_byte;
632
0
    remain_msg_byte = 0;
633
0
    ctx->remain_databitlen = 0;
634
0
  }
635
636
0
  while (databytelen >= LSH256_MSG_BLK_BYTE_LEN)
637
0
  {
638
    // This call to compress caused some trouble.
639
    // The data pointer can become unaligned in the
640
    // previous block.
641
0
    compress(ctx, data);
642
0
    data += LSH256_MSG_BLK_BYTE_LEN;
643
0
    databytelen -= LSH256_MSG_BLK_BYTE_LEN;
644
0
  }
645
646
0
  if (databytelen > 0){
647
0
    std::memcpy(ctx->last_block, data, databytelen);
648
0
    ctx->remain_databitlen = (lsh_uint)(databytelen << 3);
649
0
  }
650
651
0
  if (pos2){
652
0
    ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff);
653
0
    ctx->remain_databitlen += pos2;
654
0
  }
655
656
0
  return LSH_SUCCESS;
657
0
}
658
659
lsh_err lsh256_final(LSH256_Context* ctx, lsh_u8* hashval)
660
0
{
661
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
662
0
  CRYPTOPP_ASSERT(hashval != NULLPTR);
663
664
  // We are byte oriented. tail bits will always be 0.
665
0
  size_t remain_msg_byte = ctx->remain_databitlen >> 3;
666
  // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7;
667
0
  const size_t remain_msg_bit = 0;
668
669
0
  if (remain_msg_byte >= LSH256_MSG_BLK_BYTE_LEN){
670
0
    return LSH_ERR_INVALID_STATE;
671
0
  }
672
673
0
  if (remain_msg_bit){
674
0
    ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit));
675
0
  }
676
0
  else{
677
0
    ctx->last_block[remain_msg_byte] = 0x80;
678
0
  }
679
0
  std::memset(ctx->last_block + remain_msg_byte + 1, 0, LSH256_MSG_BLK_BYTE_LEN - remain_msg_byte - 1);
680
681
0
  compress(ctx, ctx->last_block);
682
683
0
  fin(ctx);
684
0
  get_hash(ctx, hashval);
685
686
0
  return LSH_SUCCESS;
687
0
}
688
689
ANONYMOUS_NAMESPACE_END
690
691
NAMESPACE_BEGIN(CryptoPP)
692
693
#if defined(CRYPTOPP_ENABLE_64BIT_SSE)
694
# if defined(CRYPTOPP_AVX2_AVAILABLE)
695
  extern void LSH256_Base_Restart_AVX2(word32* state);
696
  extern void LSH256_Base_Update_AVX2(word32* state, const byte *input, size_t size);
697
  extern void LSH256_Base_TruncatedFinal_AVX2(word32* state, byte *hash, size_t size);
698
# endif
699
# if defined(CRYPTOPP_SSSE3_AVAILABLE)
700
  extern void LSH256_Base_Restart_SSSE3(word32* state);
701
  extern void LSH256_Base_Update_SSSE3(word32* state, const byte *input, size_t size);
702
  extern void LSH256_Base_TruncatedFinal_SSSE3(word32* state, byte *hash, size_t size);
703
# endif
704
#endif
705
706
void LSH256_Base_Restart_CXX(word32* state)
707
0
{
708
0
  state[RemainingBits] = 0;
709
0
  LSH256_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
710
0
  lsh_err err = lsh256_init(&ctx);
711
712
0
  if (err != LSH_SUCCESS)
713
0
    throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_init failed");
714
0
}
715
716
void LSH256_Base_Update_CXX(word32* state, const byte *input, size_t size)
717
0
{
718
0
  LSH256_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
719
0
  lsh_err err = lsh256_update(&ctx, input, 8*size);
720
721
0
  if (err != LSH_SUCCESS)
722
0
    throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_update failed");
723
0
}
724
725
void LSH256_Base_TruncatedFinal_CXX(word32* state, byte *hash, size_t)
726
0
{
727
0
  LSH256_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
728
0
  lsh_err err = lsh256_final(&ctx, hash);
729
730
0
  if (err != LSH_SUCCESS)
731
0
    throw Exception(Exception::OTHER_ERROR, "LSH256_Base: lsh256_final failed");
732
0
}
733
734
std::string LSH256_Base::AlgorithmProvider() const
735
0
{
736
0
#if defined(CRYPTOPP_ENABLE_64BIT_SSE)
737
0
#if defined(CRYPTOPP_AVX2_AVAILABLE)
738
0
  if (HasAVX2())
739
0
    return "AVX2";
740
0
  else
741
0
#endif
742
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
743
0
  if (HasSSSE3())
744
0
    return "SSSE3";
745
0
  else
746
0
#endif
747
0
#endif  // CRYPTOPP_ENABLE_64BIT_SSE
748
749
0
  return "C++";
750
0
}
751
752
void LSH256_Base::Restart()
753
14.1k
{
754
14.1k
#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
755
14.1k
  if (HasAVX2())
756
14.1k
    LSH256_Base_Restart_AVX2(m_state);
757
0
  else
758
0
#endif
759
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
760
0
  if (HasSSSE3())
761
0
    LSH256_Base_Restart_SSSE3(m_state);
762
0
  else
763
0
#endif
764
765
0
  LSH256_Base_Restart_CXX(m_state);
766
14.1k
}
767
768
void LSH256_Base::Update(const byte *input, size_t size)
769
68.7k
{
770
68.7k
  CRYPTOPP_ASSERT(input != NULLPTR);
771
68.7k
  CRYPTOPP_ASSERT(size);
772
773
68.7k
#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
774
68.7k
  if (HasAVX2())
775
68.7k
    LSH256_Base_Update_AVX2(m_state, input, size);
776
0
  else
777
0
#endif
778
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
779
0
  if (HasSSSE3())
780
0
    LSH256_Base_Update_SSSE3(m_state, input, size);
781
0
  else
782
0
#endif
783
784
0
  LSH256_Base_Update_CXX(m_state, input, size);
785
68.7k
}
786
787
void LSH256_Base::TruncatedFinal(byte *hash, size_t size)
788
13.8k
{
789
13.8k
  CRYPTOPP_ASSERT(hash != NULLPTR);
790
13.8k
  ThrowIfInvalidTruncatedSize(size);
791
792
  // TODO: determine if LSH256 supports truncated hashes. See the code
793
  // in get_hash(), where a bit-length is added to the last output
794
  // byte of the hash function.
795
13.8k
  byte fullHash[LSH256_HASH_VAL_MAX_BYTE_LEN];
796
13.8k
  bool copyOut = (size < DigestSize());
797
798
13.8k
#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
799
13.8k
  if (HasAVX2())
800
13.8k
    LSH256_Base_TruncatedFinal_AVX2(m_state, copyOut ? fullHash : hash, size);
801
0
  else
802
0
#endif
803
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
804
0
  if (HasSSSE3())
805
0
    LSH256_Base_TruncatedFinal_SSSE3(m_state, copyOut ? fullHash : hash, size);
806
0
  else
807
0
#endif
808
809
0
  LSH256_Base_TruncatedFinal_CXX(m_state, copyOut ? fullHash : hash, size);
810
811
13.8k
  if (copyOut)
812
0
    std::memcpy(hash, fullHash, size);
813
814
13.8k
    Restart();
815
13.8k
}
816
817
NAMESPACE_END