Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/lsh512.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
13
#include "pch.h"
14
#include "config.h"
15
16
#include "lsh.h"
17
#include "cpu.h"
18
#include "misc.h"
19
20
ANONYMOUS_NAMESPACE_BEGIN
21
22
/* LSH Constants */
23
24
const unsigned int LSH512_MSG_BLK_BYTE_LEN = 256;
25
// const unsigned int LSH512_MSG_BLK_BIT_LEN = 2048;
26
// const unsigned int LSH512_CV_BYTE_LEN = 128;
27
const unsigned int LSH512_HASH_VAL_MAX_BYTE_LEN = 64;
28
29
// const unsigned int MSG_BLK_WORD_LEN = 32;
30
const unsigned int CV_WORD_LEN = 16;
31
const unsigned int CONST_WORD_LEN = 8;
32
const unsigned int HASH_VAL_MAX_WORD_LEN = 8;
33
const unsigned int NUM_STEPS = 28;
34
35
const unsigned int ROT_EVEN_ALPHA = 23;
36
const unsigned int ROT_EVEN_BETA = 59;
37
const unsigned int ROT_ODD_ALPHA = 7;
38
const unsigned int ROT_ODD_BETA = 3;
39
40
const unsigned int LSH_TYPE_512_512 = 0x0010040;
41
const unsigned int LSH_TYPE_512_384 = 0x0010030;
42
const unsigned int LSH_TYPE_512_256 = 0x0010020;
43
const unsigned int LSH_TYPE_512_224 = 0x001001C;
44
45
// const unsigned int LSH_TYPE_384 = LSH_TYPE_512_384;
46
// const unsigned int LSH_TYPE_512 = LSH_TYPE_512_512;
47
48
/* Error Code */
49
50
const unsigned int LSH_SUCCESS = 0x0;
51
// const unsigned int LSH_ERR_NULL_PTR = 0x2401;
52
// const unsigned int LSH_ERR_INVALID_ALGTYPE = 0x2402;
53
const unsigned int LSH_ERR_INVALID_DATABITLEN = 0x2403;
54
const unsigned int LSH_ERR_INVALID_STATE = 0x2404;
55
56
/* Index into our state array */
57
58
const unsigned int AlgorithmType = 80;
59
const unsigned int RemainingBits = 81;
60
61
NAMESPACE_END
62
63
NAMESPACE_BEGIN(CryptoPP)
64
NAMESPACE_BEGIN(LSH)
65
66
/* -------------------------------------------------------- *
67
* LSH: iv
68
* -------------------------------------------------------- */
69
70
//extern const word64 LSH512_IV224[CV_WORD_LEN];
71
//extern const word64 LSH512_IV256[CV_WORD_LEN];
72
//extern const word64 LSH512_IV384[CV_WORD_LEN];
73
//extern const word64 LSH512_IV512[CV_WORD_LEN];
74
//extern const word64 LSH512_StepConstants[CONST_WORD_LEN * NUM_STEPS];
75
76
CRYPTOPP_ALIGN_DATA(32)
77
extern
78
const word64 LSH512_IV224[CV_WORD_LEN] = {
79
  W64LIT(0x0C401E9FE8813A55), W64LIT(0x4A5F446268FD3D35), W64LIT(0xFF13E452334F612A), W64LIT(0xF8227661037E354A),
80
  W64LIT(0xA5F223723C9CA29D), W64LIT(0x95D965A11AED3979), W64LIT(0x01E23835B9AB02CC), W64LIT(0x52D49CBAD5B30616),
81
  W64LIT(0x9E5C2027773F4ED3), W64LIT(0x66A5C8801925B701), W64LIT(0x22BBC85B4C6779D9), W64LIT(0xC13171A42C559C23),
82
  W64LIT(0x31E2B67D25BE3813), W64LIT(0xD522C4DEED8E4D83), W64LIT(0xA79F5509B43FBAFE), W64LIT(0xE00D2CD88B4B6C6A),
83
};
84
85
CRYPTOPP_ALIGN_DATA(32)
86
extern
87
const word64 LSH512_IV256[CV_WORD_LEN] = {
88
  W64LIT(0x6DC57C33DF989423), W64LIT(0xD8EA7F6E8342C199), W64LIT(0x76DF8356F8603AC4), W64LIT(0x40F1B44DE838223A),
89
  W64LIT(0x39FFE7CFC31484CD), W64LIT(0x39C4326CC5281548), W64LIT(0x8A2FF85A346045D8), W64LIT(0xFF202AA46DBDD61E),
90
  W64LIT(0xCF785B3CD5FCDB8B), W64LIT(0x1F0323B64A8150BF), W64LIT(0xFF75D972F29EA355), W64LIT(0x2E567F30BF1CA9E1),
91
  W64LIT(0xB596875BF8FF6DBA), W64LIT(0xFCCA39B089EF4615), W64LIT(0xECFF4017D020B4B6), W64LIT(0x7E77384C772ED802),
92
};
93
94
CRYPTOPP_ALIGN_DATA(32)
95
extern
96
const word64 LSH512_IV384[CV_WORD_LEN] = {
97
  W64LIT(0x53156A66292808F6), W64LIT(0xB2C4F362B204C2BC), W64LIT(0xB84B7213BFA05C4E), W64LIT(0x976CEB7C1B299F73),
98
  W64LIT(0xDF0CC63C0570AE97), W64LIT(0xDA4441BAA486CE3F), W64LIT(0x6559F5D9B5F2ACC2), W64LIT(0x22DACF19B4B52A16),
99
  W64LIT(0xBBCDACEFDE80953A), W64LIT(0xC9891A2879725B3E), W64LIT(0x7C9FE6330237E440), W64LIT(0xA30BA550553F7431),
100
  W64LIT(0xBB08043FB34E3E30), W64LIT(0xA0DEC48D54618EAD), W64LIT(0x150317267464BC57), W64LIT(0x32D1501FDE63DC93)
101
};
102
103
CRYPTOPP_ALIGN_DATA(32)
104
extern
105
const word64 LSH512_IV512[CV_WORD_LEN] = {
106
  W64LIT(0xadd50f3c7f07094e), W64LIT(0xe3f3cee8f9418a4f), W64LIT(0xb527ecde5b3d0ae9), W64LIT(0x2ef6dec68076f501),
107
  W64LIT(0x8cb994cae5aca216), W64LIT(0xfbb9eae4bba48cc7), W64LIT(0x650a526174725fea), W64LIT(0x1f9a61a73f8d8085),
108
  W64LIT(0xb6607378173b539b), W64LIT(0x1bc99853b0c0b9ed), W64LIT(0xdf727fc19b182d47), W64LIT(0xdbef360cf893a457),
109
  W64LIT(0x4981f5e570147e80), W64LIT(0xd00c4490ca7d3e30), W64LIT(0x5d73940c0e4ae1ec), W64LIT(0x894085e2edb2d819)
110
};
111
112
/* -------------------------------------------------------- *
113
* LSH: step constants
114
* -------------------------------------------------------- */
115
116
extern
117
const word64 LSH512_StepConstants[CONST_WORD_LEN * NUM_STEPS] = {
118
  W64LIT(0x97884283c938982a), W64LIT(0xba1fca93533e2355), W64LIT(0xc519a2e87aeb1c03), W64LIT(0x9a0fc95462af17b1),
119
  W64LIT(0xfc3dda8ab019a82b), W64LIT(0x02825d079a895407), W64LIT(0x79f2d0a7ee06a6f7), W64LIT(0xd76d15eed9fdf5fe),
120
  W64LIT(0x1fcac64d01d0c2c1), W64LIT(0xd9ea5de69161790f), W64LIT(0xdebc8b6366071fc8), W64LIT(0xa9d91db711c6c94b),
121
  W64LIT(0x3a18653ac9c1d427), W64LIT(0x84df64a223dd5b09), W64LIT(0x6cc37895f4ad9e70), W64LIT(0x448304c8d7f3f4d5),
122
  W64LIT(0xea91134ed29383e0), W64LIT(0xc4484477f2da88e8), W64LIT(0x9b47eec96d26e8a6), W64LIT(0x82f6d4c8d89014f4),
123
  W64LIT(0x527da0048b95fb61), W64LIT(0x644406c60138648d), W64LIT(0x303c0e8aa24c0edc), W64LIT(0xc787cda0cbe8ca19),
124
  W64LIT(0x7ba46221661764ca), W64LIT(0x0c8cbc6acd6371ac), W64LIT(0xe336b836940f8f41), W64LIT(0x79cb9da168a50976),
125
  W64LIT(0xd01da49021915cb3), W64LIT(0xa84accc7399cf1f1), W64LIT(0x6c4a992cee5aeb0c), W64LIT(0x4f556e6cb4b2e3e0),
126
  W64LIT(0x200683877d7c2f45), W64LIT(0x9949273830d51db8), W64LIT(0x19eeeecaa39ed124), W64LIT(0x45693f0a0dae7fef),
127
  W64LIT(0xedc234b1b2ee1083), W64LIT(0xf3179400d68ee399), W64LIT(0xb6e3c61b4945f778), W64LIT(0xa4c3db216796c42f),
128
  W64LIT(0x268a0b04f9ab7465), W64LIT(0xe2705f6905f2d651), W64LIT(0x08ddb96e426ff53d), W64LIT(0xaea84917bc2e6f34),
129
  W64LIT(0xaff6e664a0fe9470), W64LIT(0x0aab94d765727d8c), W64LIT(0x9aa9e1648f3d702e), W64LIT(0x689efc88fe5af3d3),
130
  W64LIT(0xb0950ffea51fd98b), W64LIT(0x52cfc86ef8c92833), W64LIT(0xe69727b0b2653245), W64LIT(0x56f160d3ea9da3e2),
131
  W64LIT(0xa6dd4b059f93051f), W64LIT(0xb6406c3cd7f00996), W64LIT(0x448b45f3ccad9ec8), W64LIT(0x079b8587594ec73b),
132
  W64LIT(0x45a50ea3c4f9653b), W64LIT(0x22983767c1f15b85), W64LIT(0x7dbed8631797782b), W64LIT(0x485234be88418638),
133
  W64LIT(0x842850a5329824c5), W64LIT(0xf6aca914c7f9a04c), W64LIT(0xcfd139c07a4c670c), W64LIT(0xa3210ce0a8160242),
134
  W64LIT(0xeab3b268be5ea080), W64LIT(0xbacf9f29b34ce0a7), W64LIT(0x3c973b7aaf0fa3a8), W64LIT(0x9a86f346c9c7be80),
135
  W64LIT(0xac78f5d7cabcea49), W64LIT(0xa355bddcc199ed42), W64LIT(0xa10afa3ac6b373db), W64LIT(0xc42ded88be1844e5),
136
  W64LIT(0x9e661b271cff216a), W64LIT(0x8a6ec8dd002d8861), W64LIT(0xd3d2b629beb34be4), W64LIT(0x217a3a1091863f1a),
137
  W64LIT(0x256ecda287a733f5), W64LIT(0xf9139a9e5b872fe5), W64LIT(0xac0535017a274f7c), W64LIT(0xf21b7646d65d2aa9),
138
  W64LIT(0x048142441c208c08), W64LIT(0xf937a5dd2db5e9eb), W64LIT(0xa688dfe871ff30b7), W64LIT(0x9bb44aa217c5593b),
139
  W64LIT(0x943c702a2edb291a), W64LIT(0x0cae38f9e2b715de), W64LIT(0xb13a367ba176cc28), W64LIT(0x0d91bd1d3387d49b),
140
  W64LIT(0x85c386603cac940c), W64LIT(0x30dd830ae39fd5e4), W64LIT(0x2f68c85a712fe85d), W64LIT(0x4ffeecb9dd1e94d6),
141
  W64LIT(0xd0ac9a590a0443ae), W64LIT(0xbae732dc99ccf3ea), W64LIT(0xeb70b21d1842f4d9), W64LIT(0x9f4eda50bb5c6fa8),
142
  W64LIT(0x4949e69ce940a091), W64LIT(0x0e608dee8375ba14), W64LIT(0x983122cba118458c), W64LIT(0x4eeba696fbb36b25),
143
  W64LIT(0x7d46f3630e47f27e), W64LIT(0xa21a0f7666c0dea4), W64LIT(0x5c22cf355b37cec4), W64LIT(0xee292b0c17cc1847),
144
  W64LIT(0x9330838629e131da), W64LIT(0x6eee7c71f92fce22), W64LIT(0xc953ee6cb95dd224), W64LIT(0x3a923d92af1e9073),
145
  W64LIT(0xc43a5671563a70fb), W64LIT(0xbc2985dd279f8346), W64LIT(0x7ef2049093069320), W64LIT(0x17543723e3e46035),
146
  W64LIT(0xc3b409b00b130c6d), W64LIT(0x5d6aee6b28fdf090), W64LIT(0x1d425b26172ff6ed), W64LIT(0xcccfd041cdaf03ad),
147
  W64LIT(0xfe90c7c790ab6cbf), W64LIT(0xe5af6304c722ca02), W64LIT(0x70f695239999b39e), W64LIT(0x6b8b5b07c844954c),
148
  W64LIT(0x77bdb9bb1e1f7a30), W64LIT(0xc859599426ee80ed), W64LIT(0x5f9d813d4726e40a), W64LIT(0x9ca0120f7cb2b179),
149
  W64LIT(0x8f588f583c182cbd), W64LIT(0x951267cbe9eccce7), W64LIT(0x678bb8bd334d520e), W64LIT(0xf6e662d00cd9e1b7),
150
  W64LIT(0x357774d93d99aaa7), W64LIT(0x21b2edbb156f6eb5), W64LIT(0xfd1ebe846e0aee69), W64LIT(0x3cb2218c2f642b15),
151
  W64LIT(0xe7e7e7945444ea4c), W64LIT(0xa77a33b5d6b9b47c), W64LIT(0xf34475f0809f6075), W64LIT(0xdd4932dce6bb99ad),
152
  W64LIT(0xacec4e16d74451dc), W64LIT(0xd4a0a8d084de23d6), W64LIT(0x1bdd42f278f95866), W64LIT(0xeed3adbb938f4051),
153
  W64LIT(0xcfcf7be8992f3733), W64LIT(0x21ade98c906e3123), W64LIT(0x37ba66711fffd668), W64LIT(0x267c0fc3a255478a),
154
  W64LIT(0x993a64ee1b962e88), W64LIT(0x754979556301faaa), W64LIT(0xf920356b7251be81), W64LIT(0xc281694f22cf923f),
155
  W64LIT(0x9f4b6481c8666b02), W64LIT(0xcf97761cfe9f5444), W64LIT(0xf220d7911fd63e9f), W64LIT(0xa28bd365f79cd1b0),
156
  W64LIT(0xd39f5309b1c4b721), W64LIT(0xbec2ceb864fca51f), W64LIT(0x1955a0ddc410407a), W64LIT(0x43eab871f261d201),
157
  W64LIT(0xeaafe64a2ed16da1), W64LIT(0x670d931b9df39913), W64LIT(0x12f868b0f614de91), W64LIT(0x2e5f395d946e8252),
158
  W64LIT(0x72f25cbb767bd8f4), W64LIT(0x8191871d61a1c4dd), W64LIT(0x6ef67ea1d450ba93), W64LIT(0x2ea32a645433d344),
159
  W64LIT(0x9a963079003f0f8b), W64LIT(0x74a0aeb9918cac7a), W64LIT(0x0b6119a70af36fa3), W64LIT(0x8d9896f202f0d480),
160
  W64LIT(0x654f1831f254cd66), W64LIT(0x1318a47f0366a25e), W64LIT(0x65752076250b4e01), W64LIT(0xd1cd8eb888071772),
161
  W64LIT(0x30c6a9793f4e9b25), W64LIT(0x154f684b1e3926ee), W64LIT(0x6c7ac0b1fe6312ae), W64LIT(0x262f88f4f3c5550d),
162
  W64LIT(0xb4674a24472233cb), W64LIT(0x2bbd23826a090071), W64LIT(0xda95969b30594f66), W64LIT(0x9f5c47408f1e8a43),
163
  W64LIT(0xf77022b88de9c055), W64LIT(0x64b7b36957601503), W64LIT(0xe73b72b06175c11a), W64LIT(0x55b87de8b91a6233),
164
  W64LIT(0x1bb16e6b6955ff7f), W64LIT(0xe8e0a5ec7309719c), W64LIT(0x702c31cb89a8b640), W64LIT(0xfba387cfada8cde2),
165
  W64LIT(0x6792db4677aa164c), W64LIT(0x1c6b1cc0b7751867), W64LIT(0x22ae2311d736dc01), W64LIT(0x0e3666a1d37c9588),
166
  W64LIT(0xcd1fd9d4bf557e9a), W64LIT(0xc986925f7c7b0e84), W64LIT(0x9c5dfd55325ef6b0), W64LIT(0x9f2b577d5676b0dd),
167
  W64LIT(0xfa6e21be21c062b3), W64LIT(0x8787dd782c8d7f83), W64LIT(0xd0d134e90e12dd23), W64LIT(0x449d087550121d96),
168
  W64LIT(0xecf9ae9414d41967), W64LIT(0x5018f1dbf789934d), W64LIT(0xfa5b52879155a74c), W64LIT(0xca82d4d3cd278e7c),
169
  W64LIT(0x688fdfdfe22316ad), W64LIT(0x0f6555a4ba0d030a), W64LIT(0xa2061df720f000f3), W64LIT(0xe1a57dc5622fb3da),
170
  W64LIT(0xe6a842a8e8ed8153), W64LIT(0x690acdd3811ce09d), W64LIT(0x55adda18e6fcf446), W64LIT(0x4d57a8a0f4b60b46),
171
  W64LIT(0xf86fbfc20539c415), W64LIT(0x74bafa5ec7100d19), W64LIT(0xa824151810f0f495), W64LIT(0x8723432791e38ebb),
172
  W64LIT(0x8eeaeb91d66ed539), W64LIT(0x73d8a1549dfd7e06), W64LIT(0x0387f2ffe3f13a9b), W64LIT(0xa5004995aac15193),
173
  W64LIT(0x682f81c73efdda0d), W64LIT(0x2fb55925d71d268d), W64LIT(0xcc392d2901e58a3d), W64LIT(0xaa666ab975724a42)
174
};
175
176
NAMESPACE_END  // LSH
177
NAMESPACE_END  // Crypto++
178
179
ANONYMOUS_NAMESPACE_BEGIN
180
181
using CryptoPP::byte;
182
using CryptoPP::word32;
183
using CryptoPP::word64;
184
using CryptoPP::rotlFixed;
185
using CryptoPP::rotlConstant;
186
187
using CryptoPP::GetBlock;
188
using CryptoPP::LittleEndian;
189
using CryptoPP::ConditionalByteReverse;
190
using CryptoPP::LITTLE_ENDIAN_ORDER;
191
192
using CryptoPP::LSH::LSH512_IV224;
193
using CryptoPP::LSH::LSH512_IV256;
194
using CryptoPP::LSH::LSH512_IV384;
195
using CryptoPP::LSH::LSH512_IV512;
196
using CryptoPP::LSH::LSH512_StepConstants;
197
198
typedef byte lsh_u8;
199
typedef word32 lsh_u32;
200
typedef word64 lsh_u64;
201
typedef word32 lsh_uint;
202
typedef word32 lsh_err;
203
typedef word32 lsh_type;
204
205
struct LSH512_Context
206
{
207
  LSH512_Context(word64* state, word64 algType, word64& remainingBitLength) :
208
    cv_l(state+0), cv_r(state+8), sub_msgs(state+16),
209
    last_block(reinterpret_cast<byte*>(state+48)),
210
    remain_databitlen(remainingBitLength),
211
0
    alg_type(static_cast<lsh_type>(algType)) {}
212
213
  lsh_u64* cv_l;  // start of our state block
214
  lsh_u64* cv_r;
215
  lsh_u64* sub_msgs;
216
  lsh_u8*  last_block;
217
  lsh_u64& remain_databitlen;
218
  lsh_type alg_type;
219
};
220
221
struct LSH512_Internal
222
{
223
  LSH512_Internal(word64* state) :
224
    submsg_e_l(state+16), submsg_e_r(state+24),
225
0
    submsg_o_l(state+32), submsg_o_r(state+40) { }
226
227
  lsh_u64* submsg_e_l; /* even left sub-message  */
228
  lsh_u64* submsg_e_r; /* even right sub-message */
229
  lsh_u64* submsg_o_l; /* odd left sub-message   */
230
  lsh_u64* submsg_o_r; /* odd right sub-message  */
231
};
232
233
const lsh_u32 g_gamma512[8] = { 0, 16, 32, 48, 8, 24, 40, 56 };
234
235
/* LSH AlgType Macro */
236
237
0
inline bool LSH_IS_LSH512(lsh_uint val) {
238
0
  return (val & 0xf0000) == 0x10000;
239
0
}
240
241
0
inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) {
242
0
  return val >> 24;
243
0
}
244
245
0
inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) {
246
0
  return val & 0xffff;
247
0
}
248
249
0
inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) {
250
0
  return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val);
251
0
}
252
253
0
inline lsh_u64 loadLE64(lsh_u64 v) {
254
0
  return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, v);
255
0
}
256
257
0
lsh_u64 ROTL64(lsh_u64 x, lsh_u32 r) {
258
0
  return rotlFixed(x, r);
259
0
}
260
261
// Original code relied upon unaligned lsh_u64 buffer
262
inline void load_msg_blk(LSH512_Internal* i_state, const lsh_u8* msgblk)
263
0
{
264
0
  lsh_u64* submsg_e_l = i_state->submsg_e_l;
265
0
  lsh_u64* submsg_e_r = i_state->submsg_e_r;
266
0
  lsh_u64* submsg_o_l = i_state->submsg_o_l;
267
0
  lsh_u64* submsg_o_r = i_state->submsg_o_r;
268
269
0
  typedef GetBlock<word64, LittleEndian, false> InBlock;
270
271
0
  InBlock input(msgblk);
272
0
  input(submsg_e_l[0])(submsg_e_l[1])(submsg_e_l[2])(submsg_e_l[3])
273
0
    (submsg_e_l[4])(submsg_e_l[5])(submsg_e_l[6])(submsg_e_l[7])
274
0
    (submsg_e_r[0])(submsg_e_r[1])(submsg_e_r[2])(submsg_e_r[3])
275
0
    (submsg_e_r[4])(submsg_e_r[5])(submsg_e_r[6])(submsg_e_r[7])
276
0
    (submsg_o_l[0])(submsg_o_l[1])(submsg_o_l[2])(submsg_o_l[3])
277
0
    (submsg_o_l[4])(submsg_o_l[5])(submsg_o_l[6])(submsg_o_l[7])
278
0
    (submsg_o_r[0])(submsg_o_r[1])(submsg_o_r[2])(submsg_o_r[3])
279
0
    (submsg_o_r[4])(submsg_o_r[5])(submsg_o_r[6])(submsg_o_r[7]);
280
0
}
281
282
inline void msg_exp_even(LSH512_Internal* i_state)
283
0
{
284
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
285
286
0
  lsh_u64* submsg_e_l = i_state->submsg_e_l;
287
0
  lsh_u64* submsg_e_r = i_state->submsg_e_r;
288
0
  lsh_u64* submsg_o_l = i_state->submsg_o_l;
289
0
  lsh_u64* submsg_o_r = i_state->submsg_o_r;
290
291
0
  lsh_u64 temp;
292
0
  temp = submsg_e_l[0];
293
0
  submsg_e_l[0] = submsg_o_l[0] + submsg_e_l[3];
294
0
  submsg_e_l[3] = submsg_o_l[3] + submsg_e_l[1];
295
0
  submsg_e_l[1] = submsg_o_l[1] + submsg_e_l[2];
296
0
  submsg_e_l[2] = submsg_o_l[2] + temp;
297
0
  temp = submsg_e_l[4];
298
0
  submsg_e_l[4] = submsg_o_l[4] + submsg_e_l[7];
299
0
  submsg_e_l[7] = submsg_o_l[7] + submsg_e_l[6];
300
0
  submsg_e_l[6] = submsg_o_l[6] + submsg_e_l[5];
301
0
  submsg_e_l[5] = submsg_o_l[5] + temp;
302
0
  temp = submsg_e_r[0];
303
0
  submsg_e_r[0] = submsg_o_r[0] + submsg_e_r[3];
304
0
  submsg_e_r[3] = submsg_o_r[3] + submsg_e_r[1];
305
0
  submsg_e_r[1] = submsg_o_r[1] + submsg_e_r[2];
306
0
  submsg_e_r[2] = submsg_o_r[2] + temp;
307
0
  temp = submsg_e_r[4];
308
0
  submsg_e_r[4] = submsg_o_r[4] + submsg_e_r[7];
309
0
  submsg_e_r[7] = submsg_o_r[7] + submsg_e_r[6];
310
0
  submsg_e_r[6] = submsg_o_r[6] + submsg_e_r[5];
311
0
  submsg_e_r[5] = submsg_o_r[5] + temp;
312
0
}
313
314
inline void msg_exp_odd(LSH512_Internal* i_state)
315
0
{
316
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
317
318
0
  lsh_u64* submsg_e_l = i_state->submsg_e_l;
319
0
  lsh_u64* submsg_e_r = i_state->submsg_e_r;
320
0
  lsh_u64* submsg_o_l = i_state->submsg_o_l;
321
0
  lsh_u64* submsg_o_r = i_state->submsg_o_r;
322
323
0
  lsh_u64 temp;
324
0
  temp = submsg_o_l[0];
325
0
  submsg_o_l[0] = submsg_e_l[0] + submsg_o_l[3];
326
0
  submsg_o_l[3] = submsg_e_l[3] + submsg_o_l[1];
327
0
  submsg_o_l[1] = submsg_e_l[1] + submsg_o_l[2];
328
0
  submsg_o_l[2] = submsg_e_l[2] + temp;
329
0
  temp = submsg_o_l[4];
330
0
  submsg_o_l[4] = submsg_e_l[4] + submsg_o_l[7];
331
0
  submsg_o_l[7] = submsg_e_l[7] + submsg_o_l[6];
332
0
  submsg_o_l[6] = submsg_e_l[6] + submsg_o_l[5];
333
0
  submsg_o_l[5] = submsg_e_l[5] + temp;
334
0
  temp = submsg_o_r[0];
335
0
  submsg_o_r[0] = submsg_e_r[0] + submsg_o_r[3];
336
0
  submsg_o_r[3] = submsg_e_r[3] + submsg_o_r[1];
337
0
  submsg_o_r[1] = submsg_e_r[1] + submsg_o_r[2];
338
0
  submsg_o_r[2] = submsg_e_r[2] + temp;
339
0
  temp = submsg_o_r[4];
340
0
  submsg_o_r[4] = submsg_e_r[4] + submsg_o_r[7];
341
0
  submsg_o_r[7] = submsg_e_r[7] + submsg_o_r[6];
342
0
  submsg_o_r[6] = submsg_e_r[6] + submsg_o_r[5];
343
0
  submsg_o_r[5] = submsg_e_r[5] + temp;
344
0
}
345
346
inline void load_sc(const lsh_u64** p_const_v, size_t i)
347
0
{
348
0
  *p_const_v = &LSH512_StepConstants[i];
349
0
}
350
351
inline void msg_add_even(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_Internal* i_state)
352
0
{
353
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
354
355
0
  lsh_u64* submsg_e_l = i_state->submsg_e_l;
356
0
  lsh_u64* submsg_e_r = i_state->submsg_e_r;
357
358
0
  cv_l[0] ^= submsg_e_l[0];  cv_l[1] ^= submsg_e_l[1];
359
0
  cv_l[2] ^= submsg_e_l[2];  cv_l[3] ^= submsg_e_l[3];
360
0
  cv_l[4] ^= submsg_e_l[4];  cv_l[5] ^= submsg_e_l[5];
361
0
  cv_l[6] ^= submsg_e_l[6];  cv_l[7] ^= submsg_e_l[7];
362
0
  cv_r[0] ^= submsg_e_r[0];  cv_r[1] ^= submsg_e_r[1];
363
0
  cv_r[2] ^= submsg_e_r[2];  cv_r[3] ^= submsg_e_r[3];
364
0
  cv_r[4] ^= submsg_e_r[4];  cv_r[5] ^= submsg_e_r[5];
365
0
  cv_r[6] ^= submsg_e_r[6];  cv_r[7] ^= submsg_e_r[7];
366
0
}
367
368
inline void msg_add_odd(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_Internal* i_state)
369
0
{
370
0
  CRYPTOPP_ASSERT(i_state != NULLPTR);
371
372
0
  lsh_u64* submsg_o_l = i_state->submsg_o_l;
373
0
  lsh_u64* submsg_o_r = i_state->submsg_o_r;
374
375
0
  cv_l[0] ^= submsg_o_l[0];  cv_l[1] ^= submsg_o_l[1];
376
0
  cv_l[2] ^= submsg_o_l[2];  cv_l[3] ^= submsg_o_l[3];
377
0
  cv_l[4] ^= submsg_o_l[4];  cv_l[5] ^= submsg_o_l[5];
378
0
  cv_l[6] ^= submsg_o_l[6];  cv_l[7] ^= submsg_o_l[7];
379
0
  cv_r[0] ^= submsg_o_r[0];  cv_r[1] ^= submsg_o_r[1];
380
0
  cv_r[2] ^= submsg_o_r[2];  cv_r[3] ^= submsg_o_r[3];
381
0
  cv_r[4] ^= submsg_o_r[4];  cv_r[5] ^= submsg_o_r[5];
382
0
  cv_r[6] ^= submsg_o_r[6];  cv_r[7] ^= submsg_o_r[7];
383
0
}
384
385
inline void add_blk(lsh_u64 cv_l[8], lsh_u64 cv_r[8])
386
0
{
387
0
  cv_l[0] += cv_r[0];
388
0
  cv_l[1] += cv_r[1];
389
0
  cv_l[2] += cv_r[2];
390
0
  cv_l[3] += cv_r[3];
391
0
  cv_l[4] += cv_r[4];
392
0
  cv_l[5] += cv_r[5];
393
0
  cv_l[6] += cv_r[6];
394
0
  cv_l[7] += cv_r[7];
395
0
}
396
397
template <unsigned int R>
398
inline void rotate_blk(lsh_u64 cv[8])
399
0
{
400
0
  cv[0] = rotlConstant<R>(cv[0]);
401
0
  cv[1] = rotlConstant<R>(cv[1]);
402
0
  cv[2] = rotlConstant<R>(cv[2]);
403
0
  cv[3] = rotlConstant<R>(cv[3]);
404
0
  cv[4] = rotlConstant<R>(cv[4]);
405
0
  cv[5] = rotlConstant<R>(cv[5]);
406
0
  cv[6] = rotlConstant<R>(cv[6]);
407
0
  cv[7] = rotlConstant<R>(cv[7]);
408
0
}
Unexecuted instantiation: lsh512.cpp:void (anonymous namespace)::rotate_blk<23u>(unsigned long*)
Unexecuted instantiation: lsh512.cpp:void (anonymous namespace)::rotate_blk<59u>(unsigned long*)
Unexecuted instantiation: lsh512.cpp:void (anonymous namespace)::rotate_blk<7u>(unsigned long*)
Unexecuted instantiation: lsh512.cpp:void (anonymous namespace)::rotate_blk<3u>(unsigned long*)
409
410
inline void xor_with_const(lsh_u64 cv_l[8], const lsh_u64* const_v)
411
0
{
412
0
  cv_l[0] ^= const_v[0];
413
0
  cv_l[1] ^= const_v[1];
414
0
  cv_l[2] ^= const_v[2];
415
0
  cv_l[3] ^= const_v[3];
416
0
  cv_l[4] ^= const_v[4];
417
0
  cv_l[5] ^= const_v[5];
418
0
  cv_l[6] ^= const_v[6];
419
0
  cv_l[7] ^= const_v[7];
420
0
}
421
422
inline void rotate_msg_gamma(lsh_u64 cv_r[8])
423
0
{
424
0
  cv_r[1] = ROTL64(cv_r[1], g_gamma512[1]);
425
0
  cv_r[2] = ROTL64(cv_r[2], g_gamma512[2]);
426
0
  cv_r[3] = ROTL64(cv_r[3], g_gamma512[3]);
427
0
  cv_r[4] = ROTL64(cv_r[4], g_gamma512[4]);
428
0
  cv_r[5] = ROTL64(cv_r[5], g_gamma512[5]);
429
0
  cv_r[6] = ROTL64(cv_r[6], g_gamma512[6]);
430
0
  cv_r[7] = ROTL64(cv_r[7], g_gamma512[7]);
431
0
}
432
433
inline void word_perm(lsh_u64 cv_l[8], lsh_u64 cv_r[8])
434
0
{
435
0
  lsh_u64 temp;
436
0
  temp = cv_l[0];
437
0
  cv_l[0] = cv_l[6];
438
0
  cv_l[6] = cv_r[6];
439
0
  cv_r[6] = cv_r[2];
440
0
  cv_r[2] = cv_l[1];
441
0
  cv_l[1] = cv_l[4];
442
0
  cv_l[4] = cv_r[4];
443
0
  cv_r[4] = cv_r[0];
444
0
  cv_r[0] = cv_l[2];
445
0
  cv_l[2] = cv_l[5];
446
0
  cv_l[5] = cv_r[7];
447
0
  cv_r[7] = cv_r[1];
448
0
  cv_r[1] = temp;
449
0
  temp = cv_l[3];
450
0
  cv_l[3] = cv_l[7];
451
0
  cv_l[7] = cv_r[5];
452
0
  cv_r[5] = cv_r[3];
453
0
  cv_r[3] = temp;
454
0
}
455
456
/* -------------------------------------------------------- *
457
* step function
458
* -------------------------------------------------------- */
459
460
template <unsigned int Alpha, unsigned int Beta>
461
inline void mix(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 const_v[8])
462
0
{
463
0
  add_blk(cv_l, cv_r);
464
0
  rotate_blk<Alpha>(cv_l);
465
0
  xor_with_const(cv_l, const_v);
466
0
  add_blk(cv_r, cv_l);
467
0
  rotate_blk<Beta>(cv_r);
468
0
  add_blk(cv_l, cv_r);
469
0
  rotate_msg_gamma(cv_r);
470
0
}
Unexecuted instantiation: lsh512.cpp:void (anonymous namespace)::mix<23u, 59u>(unsigned long*, unsigned long*, unsigned long const*)
Unexecuted instantiation: lsh512.cpp:void (anonymous namespace)::mix<7u, 3u>(unsigned long*, unsigned long*, unsigned long const*)
471
472
/* -------------------------------------------------------- *
473
* compression function
474
* -------------------------------------------------------- */
475
476
inline void compress(LSH512_Context* ctx, const lsh_u8 pdMsgBlk[LSH512_MSG_BLK_BYTE_LEN])
477
0
{
478
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
479
480
0
  LSH512_Internal  s_state(ctx->cv_l);
481
0
  LSH512_Internal* i_state = &s_state;
482
483
0
  const lsh_u64* const_v = NULL;
484
0
  lsh_u64 *cv_l = ctx->cv_l;
485
0
  lsh_u64 *cv_r = ctx->cv_r;
486
487
0
  load_msg_blk(i_state, pdMsgBlk);
488
489
0
  msg_add_even(cv_l, cv_r, i_state);
490
0
  load_sc(&const_v, 0);
491
0
  mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
492
0
  word_perm(cv_l, cv_r);
493
494
0
  msg_add_odd(cv_l, cv_r, i_state);
495
0
  load_sc(&const_v, 8);
496
0
  mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
497
0
  word_perm(cv_l, cv_r);
498
499
0
  for (size_t i = 1; i < NUM_STEPS / 2; i++)
500
0
  {
501
0
    msg_exp_even(i_state);
502
0
    msg_add_even(cv_l, cv_r, i_state);
503
0
    load_sc(&const_v, 16 * i);
504
0
    mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
505
0
    word_perm(cv_l, cv_r);
506
507
0
    msg_exp_odd(i_state);
508
0
    msg_add_odd(cv_l, cv_r, i_state);
509
0
    load_sc(&const_v, 16 * i + 8);
510
0
    mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
511
0
    word_perm(cv_l, cv_r);
512
0
  }
513
514
0
  msg_exp_even(i_state);
515
0
  msg_add_even(cv_l, cv_r, i_state);
516
0
}
517
518
/* -------------------------------------------------------- */
519
520
inline void load_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 iv[16])
521
0
{
522
0
  cv_l[0] = iv[0];
523
0
  cv_l[1] = iv[1];
524
0
  cv_l[2] = iv[2];
525
0
  cv_l[3] = iv[3];
526
0
  cv_l[4] = iv[4];
527
0
  cv_l[5] = iv[5];
528
0
  cv_l[6] = iv[6];
529
0
  cv_l[7] = iv[7];
530
0
  cv_r[0] = iv[8];
531
0
  cv_r[1] = iv[9];
532
0
  cv_r[2] = iv[10];
533
0
  cv_r[3] = iv[11];
534
0
  cv_r[4] = iv[12];
535
0
  cv_r[5] = iv[13];
536
0
  cv_r[6] = iv[14];
537
0
  cv_r[7] = iv[15];
538
0
}
539
540
inline void zero_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8])
541
0
{
542
0
  std::memset(cv_l, 0, 8*sizeof(lsh_u64));
543
0
  std::memset(cv_r, 0, 8*sizeof(lsh_u64));
544
0
}
545
546
inline void zero_submsgs(LSH512_Context* ctx)
547
0
{
548
0
  lsh_u64* sub_msgs = ctx->sub_msgs;
549
550
0
  std::memset(sub_msgs, 0x00, 32*sizeof(lsh_u64));
551
0
}
552
553
inline void init224(LSH512_Context* ctx)
554
0
{
555
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
556
557
0
  zero_submsgs(ctx);
558
0
  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV224);
559
0
}
560
561
inline void init256(LSH512_Context* ctx)
562
0
{
563
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
564
565
0
  zero_submsgs(ctx);
566
0
  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV256);
567
0
}
568
569
inline void init384(LSH512_Context* ctx)
570
0
{
571
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
572
573
0
  zero_submsgs(ctx);
574
0
  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV384);
575
0
}
576
577
inline void init512(LSH512_Context* ctx)
578
0
{
579
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
580
581
0
  zero_submsgs(ctx);
582
0
  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV512);
583
0
}
584
585
/* -------------------------------------------------------- */
586
587
inline void fin(LSH512_Context* ctx)
588
0
{
589
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
590
591
0
  for (size_t i = 0; i < HASH_VAL_MAX_WORD_LEN; i++){
592
0
    ctx->cv_l[i] = loadLE64(ctx->cv_l[i] ^ ctx->cv_r[i]);
593
0
  }
594
0
}
595
596
/* -------------------------------------------------------- */
597
598
inline void get_hash(LSH512_Context* ctx, lsh_u8* pbHashVal)
599
0
{
600
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
601
0
  CRYPTOPP_ASSERT(ctx->alg_type != 0);
602
0
  CRYPTOPP_ASSERT(pbHashVal != NULLPTR);
603
604
0
  lsh_uint alg_type = ctx->alg_type;
605
0
  lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type);
606
0
  lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type);
607
608
  // Multiplying by looks odd...
609
0
  std::memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len);
610
0
  if (hash_val_bit_len){
611
0
    pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len);
612
0
  }
613
0
}
614
615
/* -------------------------------------------------------- */
616
617
lsh_err lsh512_init(LSH512_Context* ctx)
618
0
{
619
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
620
0
  CRYPTOPP_ASSERT(ctx->alg_type != 0);
621
622
0
  lsh_u32 alg_type = ctx->alg_type;
623
0
  const lsh_u64* const_v = NULL;
624
0
  ctx->remain_databitlen = 0;
625
626
0
  switch (alg_type){
627
0
  case LSH_TYPE_512_512:
628
0
    init512(ctx);
629
0
    return LSH_SUCCESS;
630
0
  case LSH_TYPE_512_384:
631
0
    init384(ctx);
632
0
    return LSH_SUCCESS;
633
0
  case LSH_TYPE_512_256:
634
0
    init256(ctx);
635
0
    return LSH_SUCCESS;
636
0
  case LSH_TYPE_512_224:
637
0
    init224(ctx);
638
0
    return LSH_SUCCESS;
639
0
  default:
640
0
    break;
641
0
  }
642
643
0
  lsh_u64* cv_l = ctx->cv_l;
644
0
  lsh_u64* cv_r = ctx->cv_r;
645
646
0
  zero_iv(cv_l, cv_r);
647
0
  cv_l[0] = LSH512_HASH_VAL_MAX_BYTE_LEN;
648
0
  cv_l[1] = LSH_GET_HASHBIT(alg_type);
649
650
0
  for (size_t i = 0; i < NUM_STEPS / 2; i++)
651
0
  {
652
    //Mix
653
0
    load_sc(&const_v, i * 16);
654
0
    mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
655
0
    word_perm(cv_l, cv_r);
656
657
0
    load_sc(&const_v, i * 16 + 8);
658
0
    mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
659
0
    word_perm(cv_l, cv_r);
660
0
  }
661
662
0
  return LSH_SUCCESS;
663
0
}
664
665
lsh_err lsh512_update(LSH512_Context* ctx, const lsh_u8* data, size_t databitlen)
666
0
{
667
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
668
0
  CRYPTOPP_ASSERT(data != NULLPTR);
669
0
  CRYPTOPP_ASSERT(databitlen % 8 == 0);
670
0
  CRYPTOPP_ASSERT(ctx->alg_type != 0);
671
672
0
  if (databitlen == 0){
673
0
    return LSH_SUCCESS;
674
0
  }
675
676
  // We are byte oriented. tail bits will always be 0.
677
0
  size_t databytelen = databitlen >> 3;
678
  // lsh_uint pos2 = databitlen & 0x7;
679
0
  const size_t pos2 = 0;
680
681
0
  size_t remain_msg_byte = static_cast<size_t>(ctx->remain_databitlen >> 3);
682
  // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7;
683
0
  const size_t remain_msg_bit = 0;
684
685
0
  if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){
686
0
    return LSH_ERR_INVALID_STATE;
687
0
  }
688
0
  if (remain_msg_bit > 0){
689
0
    return LSH_ERR_INVALID_DATABITLEN;
690
0
  }
691
692
0
  if (databytelen + remain_msg_byte < LSH512_MSG_BLK_BYTE_LEN){
693
0
    std::memcpy(ctx->last_block + remain_msg_byte, data, databytelen);
694
0
    ctx->remain_databitlen += (lsh_uint)databitlen;
695
0
    remain_msg_byte += (lsh_uint)databytelen;
696
0
    if (pos2){
697
0
      ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff);
698
0
    }
699
0
    return LSH_SUCCESS;
700
0
  }
701
702
0
  if (remain_msg_byte > 0){
703
0
    size_t more_byte = LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte;
704
0
    std::memcpy(ctx->last_block + remain_msg_byte, data, more_byte);
705
0
    compress(ctx, ctx->last_block);
706
0
    data += more_byte;
707
0
    databytelen -= more_byte;
708
0
    remain_msg_byte = 0;
709
0
    ctx->remain_databitlen = 0;
710
0
  }
711
712
0
  while (databytelen >= LSH512_MSG_BLK_BYTE_LEN)
713
0
  {
714
    // This call to compress caused some trouble.
715
    // The data pointer can become unaligned in the
716
    // previous block.
717
0
    compress(ctx, data);
718
0
    data += LSH512_MSG_BLK_BYTE_LEN;
719
0
    databytelen -= LSH512_MSG_BLK_BYTE_LEN;
720
0
  }
721
722
0
  if (databytelen > 0){
723
0
    std::memcpy(ctx->last_block, data, databytelen);
724
0
    ctx->remain_databitlen = (lsh_uint)(databytelen << 3);
725
0
  }
726
727
0
  if (pos2){
728
0
    ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff);
729
0
    ctx->remain_databitlen += pos2;
730
0
  }
731
0
  return LSH_SUCCESS;
732
0
}
733
734
lsh_err lsh512_final(LSH512_Context* ctx, lsh_u8* hashval)
735
0
{
736
0
  CRYPTOPP_ASSERT(ctx != NULLPTR);
737
0
  CRYPTOPP_ASSERT(hashval != NULLPTR);
738
739
  // We are byte oriented. tail bits will always be 0.
740
0
  size_t remain_msg_byte = static_cast<size_t>(ctx->remain_databitlen >> 3);
741
  // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7;
742
0
  const size_t remain_msg_bit = 0;
743
744
0
  if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){
745
0
    return LSH_ERR_INVALID_STATE;
746
0
  }
747
748
0
  if (remain_msg_bit){
749
0
    ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit));
750
0
  }
751
0
  else{
752
0
    ctx->last_block[remain_msg_byte] = 0x80;
753
0
  }
754
0
  std::memset(ctx->last_block + remain_msg_byte + 1, 0, LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte - 1);
755
756
0
  compress(ctx, ctx->last_block);
757
758
0
  fin(ctx);
759
0
  get_hash(ctx, hashval);
760
761
0
  return LSH_SUCCESS;
762
0
}
763
764
ANONYMOUS_NAMESPACE_END
765
766
NAMESPACE_BEGIN(CryptoPP)
767
768
#if defined(CRYPTOPP_ENABLE_64BIT_SSE)
769
# if defined(CRYPTOPP_AVX2_AVAILABLE)
770
  extern void LSH512_Base_Restart_AVX2(word64* state);
771
  extern void LSH512_Base_Update_AVX2(word64* state, const byte *input, size_t size);
772
  extern void LSH512_Base_TruncatedFinal_AVX2(word64* state, byte *hash, size_t size);
773
# endif
774
# if defined(CRYPTOPP_SSSE3_AVAILABLE)
775
  extern void LSH512_Base_Restart_SSSE3(word64* state);
776
  extern void LSH512_Base_Update_SSSE3(word64* state, const byte *input, size_t size);
777
  extern void LSH512_Base_TruncatedFinal_SSSE3(word64* state, byte *hash, size_t size);
778
# endif
779
#endif
780
781
std::string LSH512_Base::AlgorithmProvider() const
782
0
{
783
0
#if defined(CRYPTOPP_ENABLE_64BIT_SSE)
784
0
#if defined(CRYPTOPP_AVX2_AVAILABLE)
785
0
  if (HasAVX2())
786
0
    return "AVX2";
787
0
  else
788
0
#endif
789
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
790
0
  if (HasSSSE3())
791
0
    return "SSSE3";
792
0
  else
793
0
#endif
794
0
#endif  // CRYPTOPP_ENABLE_64BIT_SSE
795
796
0
  return "C++";
797
0
}
798
799
void LSH512_Base_Restart_CXX(word64* state)
800
0
{
801
0
  state[RemainingBits] = 0;
802
0
  LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
803
0
  lsh_err err = lsh512_init(&ctx);
804
805
0
  if (err != LSH_SUCCESS)
806
0
    throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_init failed");
807
0
}
808
809
void LSH512_Base_Update_CXX(word64* state, const byte *input, size_t size)
810
0
{
811
0
  LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
812
0
  lsh_err err = lsh512_update(&ctx, input, 8*size);
813
814
0
  if (err != LSH_SUCCESS)
815
0
    throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_update failed");
816
0
}
817
818
void LSH512_Base_TruncatedFinal_CXX(word64* state, byte *hash, size_t)
819
0
{
820
0
  LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
821
0
  lsh_err err = lsh512_final(&ctx, hash);
822
823
0
  if (err != LSH_SUCCESS)
824
0
    throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_final failed");
825
0
}
826
827
828
void LSH512_Base::Restart()
829
18.2k
{
830
18.2k
#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
831
18.2k
  if (HasAVX2())
832
18.2k
    LSH512_Base_Restart_AVX2(m_state);
833
0
  else
834
0
#endif
835
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
836
0
  if (HasSSSE3())
837
0
    LSH512_Base_Restart_SSSE3(m_state);
838
0
  else
839
0
#endif
840
841
0
  LSH512_Base_Restart_CXX(m_state);
842
18.2k
}
843
844
void LSH512_Base::Update(const byte *input, size_t size)
845
93.3k
{
846
93.3k
  CRYPTOPP_ASSERT(input != NULLPTR);
847
93.3k
  CRYPTOPP_ASSERT(size);
848
849
93.3k
#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
850
93.3k
  if (HasAVX2())
851
93.3k
    LSH512_Base_Update_AVX2(m_state, input, size);
852
0
  else
853
0
#endif
854
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
855
0
  if (HasSSSE3())
856
0
    LSH512_Base_Update_SSSE3(m_state, input, size);
857
0
  else
858
0
#endif
859
860
0
  LSH512_Base_Update_CXX(m_state, input, size);
861
93.3k
}
862
863
void LSH512_Base::TruncatedFinal(byte *hash, size_t size)
864
17.8k
{
865
17.8k
  CRYPTOPP_ASSERT(hash != NULLPTR);
866
17.8k
  ThrowIfInvalidTruncatedSize(size);
867
868
  // TODO: determine if LSH512 supports truncated hashes. See the code
869
  // in get_hash(), where a bit-length is added to the last output
870
  // byte of the hash function.
871
17.8k
  byte fullHash[LSH512_HASH_VAL_MAX_BYTE_LEN];
872
17.8k
  bool copyOut = (size < DigestSize());
873
874
17.8k
#if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
875
17.8k
  if (HasAVX2())
876
17.8k
    LSH512_Base_TruncatedFinal_AVX2(m_state, copyOut ? fullHash : hash, size);
877
0
  else
878
0
#endif
879
0
#if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
880
0
  if (HasSSSE3())
881
0
    LSH512_Base_TruncatedFinal_SSSE3(m_state, copyOut ? fullHash : hash, size);
882
0
  else
883
0
#endif
884
885
0
  LSH512_Base_TruncatedFinal_CXX(m_state, copyOut ? fullHash : hash, size);
886
887
17.8k
  if (copyOut)
888
0
    std::memcpy(hash, fullHash, size);
889
890
17.8k
    Restart();
891
17.8k
}
892
893
NAMESPACE_END