Crypto++  8.8
Free C++ class library of cryptographic schemes
lsh512.cpp
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;
186 
187 using CryptoPP::GetBlock;
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  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  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 inline bool LSH_IS_LSH512(lsh_uint val) {
238  return (val & 0xf0000) == 0x10000;
239 }
240 
241 inline lsh_uint LSH_GET_SMALL_HASHBIT(lsh_uint val) {
242  return val >> 24;
243 }
244 
245 inline lsh_uint LSH_GET_HASHBYTE(lsh_uint val) {
246  return val & 0xffff;
247 }
248 
249 inline lsh_uint LSH_GET_HASHBIT(lsh_uint val) {
250  return (LSH_GET_HASHBYTE(val) << 3) - LSH_GET_SMALL_HASHBIT(val);
251 }
252 
253 inline lsh_u64 loadLE64(lsh_u64 v) {
255 }
256 
257 lsh_u64 ROTL64(lsh_u64 x, lsh_u32 r) {
258  return rotlFixed(x, r);
259 }
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 {
264  lsh_u64* submsg_e_l = i_state->submsg_e_l;
265  lsh_u64* submsg_e_r = i_state->submsg_e_r;
266  lsh_u64* submsg_o_l = i_state->submsg_o_l;
267  lsh_u64* submsg_o_r = i_state->submsg_o_r;
268 
270 
271  InBlock input(msgblk);
272  input(submsg_e_l[0])(submsg_e_l[1])(submsg_e_l[2])(submsg_e_l[3])
273  (submsg_e_l[4])(submsg_e_l[5])(submsg_e_l[6])(submsg_e_l[7])
274  (submsg_e_r[0])(submsg_e_r[1])(submsg_e_r[2])(submsg_e_r[3])
275  (submsg_e_r[4])(submsg_e_r[5])(submsg_e_r[6])(submsg_e_r[7])
276  (submsg_o_l[0])(submsg_o_l[1])(submsg_o_l[2])(submsg_o_l[3])
277  (submsg_o_l[4])(submsg_o_l[5])(submsg_o_l[6])(submsg_o_l[7])
278  (submsg_o_r[0])(submsg_o_r[1])(submsg_o_r[2])(submsg_o_r[3])
279  (submsg_o_r[4])(submsg_o_r[5])(submsg_o_r[6])(submsg_o_r[7]);
280 }
281 
282 inline void msg_exp_even(LSH512_Internal* i_state)
283 {
284  CRYPTOPP_ASSERT(i_state != NULLPTR);
285 
286  lsh_u64* submsg_e_l = i_state->submsg_e_l;
287  lsh_u64* submsg_e_r = i_state->submsg_e_r;
288  lsh_u64* submsg_o_l = i_state->submsg_o_l;
289  lsh_u64* submsg_o_r = i_state->submsg_o_r;
290 
291  lsh_u64 temp;
292  temp = submsg_e_l[0];
293  submsg_e_l[0] = submsg_o_l[0] + submsg_e_l[3];
294  submsg_e_l[3] = submsg_o_l[3] + submsg_e_l[1];
295  submsg_e_l[1] = submsg_o_l[1] + submsg_e_l[2];
296  submsg_e_l[2] = submsg_o_l[2] + temp;
297  temp = submsg_e_l[4];
298  submsg_e_l[4] = submsg_o_l[4] + submsg_e_l[7];
299  submsg_e_l[7] = submsg_o_l[7] + submsg_e_l[6];
300  submsg_e_l[6] = submsg_o_l[6] + submsg_e_l[5];
301  submsg_e_l[5] = submsg_o_l[5] + temp;
302  temp = submsg_e_r[0];
303  submsg_e_r[0] = submsg_o_r[0] + submsg_e_r[3];
304  submsg_e_r[3] = submsg_o_r[3] + submsg_e_r[1];
305  submsg_e_r[1] = submsg_o_r[1] + submsg_e_r[2];
306  submsg_e_r[2] = submsg_o_r[2] + temp;
307  temp = submsg_e_r[4];
308  submsg_e_r[4] = submsg_o_r[4] + submsg_e_r[7];
309  submsg_e_r[7] = submsg_o_r[7] + submsg_e_r[6];
310  submsg_e_r[6] = submsg_o_r[6] + submsg_e_r[5];
311  submsg_e_r[5] = submsg_o_r[5] + temp;
312 }
313 
314 inline void msg_exp_odd(LSH512_Internal* i_state)
315 {
316  CRYPTOPP_ASSERT(i_state != NULLPTR);
317 
318  lsh_u64* submsg_e_l = i_state->submsg_e_l;
319  lsh_u64* submsg_e_r = i_state->submsg_e_r;
320  lsh_u64* submsg_o_l = i_state->submsg_o_l;
321  lsh_u64* submsg_o_r = i_state->submsg_o_r;
322 
323  lsh_u64 temp;
324  temp = submsg_o_l[0];
325  submsg_o_l[0] = submsg_e_l[0] + submsg_o_l[3];
326  submsg_o_l[3] = submsg_e_l[3] + submsg_o_l[1];
327  submsg_o_l[1] = submsg_e_l[1] + submsg_o_l[2];
328  submsg_o_l[2] = submsg_e_l[2] + temp;
329  temp = submsg_o_l[4];
330  submsg_o_l[4] = submsg_e_l[4] + submsg_o_l[7];
331  submsg_o_l[7] = submsg_e_l[7] + submsg_o_l[6];
332  submsg_o_l[6] = submsg_e_l[6] + submsg_o_l[5];
333  submsg_o_l[5] = submsg_e_l[5] + temp;
334  temp = submsg_o_r[0];
335  submsg_o_r[0] = submsg_e_r[0] + submsg_o_r[3];
336  submsg_o_r[3] = submsg_e_r[3] + submsg_o_r[1];
337  submsg_o_r[1] = submsg_e_r[1] + submsg_o_r[2];
338  submsg_o_r[2] = submsg_e_r[2] + temp;
339  temp = submsg_o_r[4];
340  submsg_o_r[4] = submsg_e_r[4] + submsg_o_r[7];
341  submsg_o_r[7] = submsg_e_r[7] + submsg_o_r[6];
342  submsg_o_r[6] = submsg_e_r[6] + submsg_o_r[5];
343  submsg_o_r[5] = submsg_e_r[5] + temp;
344 }
345 
346 inline void load_sc(const lsh_u64** p_const_v, size_t i)
347 {
348  *p_const_v = &LSH512_StepConstants[i];
349 }
350 
351 inline void msg_add_even(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_Internal* i_state)
352 {
353  CRYPTOPP_ASSERT(i_state != NULLPTR);
354 
355  lsh_u64* submsg_e_l = i_state->submsg_e_l;
356  lsh_u64* submsg_e_r = i_state->submsg_e_r;
357 
358  cv_l[0] ^= submsg_e_l[0]; cv_l[1] ^= submsg_e_l[1];
359  cv_l[2] ^= submsg_e_l[2]; cv_l[3] ^= submsg_e_l[3];
360  cv_l[4] ^= submsg_e_l[4]; cv_l[5] ^= submsg_e_l[5];
361  cv_l[6] ^= submsg_e_l[6]; cv_l[7] ^= submsg_e_l[7];
362  cv_r[0] ^= submsg_e_r[0]; cv_r[1] ^= submsg_e_r[1];
363  cv_r[2] ^= submsg_e_r[2]; cv_r[3] ^= submsg_e_r[3];
364  cv_r[4] ^= submsg_e_r[4]; cv_r[5] ^= submsg_e_r[5];
365  cv_r[6] ^= submsg_e_r[6]; cv_r[7] ^= submsg_e_r[7];
366 }
367 
368 inline void msg_add_odd(lsh_u64 cv_l[8], lsh_u64 cv_r[8], LSH512_Internal* i_state)
369 {
370  CRYPTOPP_ASSERT(i_state != NULLPTR);
371 
372  lsh_u64* submsg_o_l = i_state->submsg_o_l;
373  lsh_u64* submsg_o_r = i_state->submsg_o_r;
374 
375  cv_l[0] ^= submsg_o_l[0]; cv_l[1] ^= submsg_o_l[1];
376  cv_l[2] ^= submsg_o_l[2]; cv_l[3] ^= submsg_o_l[3];
377  cv_l[4] ^= submsg_o_l[4]; cv_l[5] ^= submsg_o_l[5];
378  cv_l[6] ^= submsg_o_l[6]; cv_l[7] ^= submsg_o_l[7];
379  cv_r[0] ^= submsg_o_r[0]; cv_r[1] ^= submsg_o_r[1];
380  cv_r[2] ^= submsg_o_r[2]; cv_r[3] ^= submsg_o_r[3];
381  cv_r[4] ^= submsg_o_r[4]; cv_r[5] ^= submsg_o_r[5];
382  cv_r[6] ^= submsg_o_r[6]; cv_r[7] ^= submsg_o_r[7];
383 }
384 
385 inline void add_blk(lsh_u64 cv_l[8], lsh_u64 cv_r[8])
386 {
387  cv_l[0] += cv_r[0];
388  cv_l[1] += cv_r[1];
389  cv_l[2] += cv_r[2];
390  cv_l[3] += cv_r[3];
391  cv_l[4] += cv_r[4];
392  cv_l[5] += cv_r[5];
393  cv_l[6] += cv_r[6];
394  cv_l[7] += cv_r[7];
395 }
396 
397 template <unsigned int R>
398 inline void rotate_blk(lsh_u64 cv[8])
399 {
400  cv[0] = rotlConstant<R>(cv[0]);
401  cv[1] = rotlConstant<R>(cv[1]);
402  cv[2] = rotlConstant<R>(cv[2]);
403  cv[3] = rotlConstant<R>(cv[3]);
404  cv[4] = rotlConstant<R>(cv[4]);
405  cv[5] = rotlConstant<R>(cv[5]);
406  cv[6] = rotlConstant<R>(cv[6]);
407  cv[7] = rotlConstant<R>(cv[7]);
408 }
409 
410 inline void xor_with_const(lsh_u64 cv_l[8], const lsh_u64* const_v)
411 {
412  cv_l[0] ^= const_v[0];
413  cv_l[1] ^= const_v[1];
414  cv_l[2] ^= const_v[2];
415  cv_l[3] ^= const_v[3];
416  cv_l[4] ^= const_v[4];
417  cv_l[5] ^= const_v[5];
418  cv_l[6] ^= const_v[6];
419  cv_l[7] ^= const_v[7];
420 }
421 
422 inline void rotate_msg_gamma(lsh_u64 cv_r[8])
423 {
424  cv_r[1] = ROTL64(cv_r[1], g_gamma512[1]);
425  cv_r[2] = ROTL64(cv_r[2], g_gamma512[2]);
426  cv_r[3] = ROTL64(cv_r[3], g_gamma512[3]);
427  cv_r[4] = ROTL64(cv_r[4], g_gamma512[4]);
428  cv_r[5] = ROTL64(cv_r[5], g_gamma512[5]);
429  cv_r[6] = ROTL64(cv_r[6], g_gamma512[6]);
430  cv_r[7] = ROTL64(cv_r[7], g_gamma512[7]);
431 }
432 
433 inline void word_perm(lsh_u64 cv_l[8], lsh_u64 cv_r[8])
434 {
435  lsh_u64 temp;
436  temp = cv_l[0];
437  cv_l[0] = cv_l[6];
438  cv_l[6] = cv_r[6];
439  cv_r[6] = cv_r[2];
440  cv_r[2] = cv_l[1];
441  cv_l[1] = cv_l[4];
442  cv_l[4] = cv_r[4];
443  cv_r[4] = cv_r[0];
444  cv_r[0] = cv_l[2];
445  cv_l[2] = cv_l[5];
446  cv_l[5] = cv_r[7];
447  cv_r[7] = cv_r[1];
448  cv_r[1] = temp;
449  temp = cv_l[3];
450  cv_l[3] = cv_l[7];
451  cv_l[7] = cv_r[5];
452  cv_r[5] = cv_r[3];
453  cv_r[3] = temp;
454 }
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 {
463  add_blk(cv_l, cv_r);
464  rotate_blk<Alpha>(cv_l);
465  xor_with_const(cv_l, const_v);
466  add_blk(cv_r, cv_l);
467  rotate_blk<Beta>(cv_r);
468  add_blk(cv_l, cv_r);
469  rotate_msg_gamma(cv_r);
470 }
471 
472 /* -------------------------------------------------------- *
473 * compression function
474 * -------------------------------------------------------- */
475 
476 inline void compress(LSH512_Context* ctx, const lsh_u8 pdMsgBlk[LSH512_MSG_BLK_BYTE_LEN])
477 {
478  CRYPTOPP_ASSERT(ctx != NULLPTR);
479 
480  LSH512_Internal s_state(ctx->cv_l);
481  LSH512_Internal* i_state = &s_state;
482 
483  const lsh_u64* const_v = NULL;
484  lsh_u64 *cv_l = ctx->cv_l;
485  lsh_u64 *cv_r = ctx->cv_r;
486 
487  load_msg_blk(i_state, pdMsgBlk);
488 
489  msg_add_even(cv_l, cv_r, i_state);
490  load_sc(&const_v, 0);
491  mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
492  word_perm(cv_l, cv_r);
493 
494  msg_add_odd(cv_l, cv_r, i_state);
495  load_sc(&const_v, 8);
496  mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
497  word_perm(cv_l, cv_r);
498 
499  for (size_t i = 1; i < NUM_STEPS / 2; i++)
500  {
501  msg_exp_even(i_state);
502  msg_add_even(cv_l, cv_r, i_state);
503  load_sc(&const_v, 16 * i);
504  mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
505  word_perm(cv_l, cv_r);
506 
507  msg_exp_odd(i_state);
508  msg_add_odd(cv_l, cv_r, i_state);
509  load_sc(&const_v, 16 * i + 8);
510  mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
511  word_perm(cv_l, cv_r);
512  }
513 
514  msg_exp_even(i_state);
515  msg_add_even(cv_l, cv_r, i_state);
516 }
517 
518 /* -------------------------------------------------------- */
519 
520 inline void load_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8], const lsh_u64 iv[16])
521 {
522  cv_l[0] = iv[0];
523  cv_l[1] = iv[1];
524  cv_l[2] = iv[2];
525  cv_l[3] = iv[3];
526  cv_l[4] = iv[4];
527  cv_l[5] = iv[5];
528  cv_l[6] = iv[6];
529  cv_l[7] = iv[7];
530  cv_r[0] = iv[8];
531  cv_r[1] = iv[9];
532  cv_r[2] = iv[10];
533  cv_r[3] = iv[11];
534  cv_r[4] = iv[12];
535  cv_r[5] = iv[13];
536  cv_r[6] = iv[14];
537  cv_r[7] = iv[15];
538 }
539 
540 inline void zero_iv(lsh_u64 cv_l[8], lsh_u64 cv_r[8])
541 {
542  std::memset(cv_l, 0, 8*sizeof(lsh_u64));
543  std::memset(cv_r, 0, 8*sizeof(lsh_u64));
544 }
545 
546 inline void zero_submsgs(LSH512_Context* ctx)
547 {
548  lsh_u64* sub_msgs = ctx->sub_msgs;
549 
550  std::memset(sub_msgs, 0x00, 32*sizeof(lsh_u64));
551 }
552 
553 inline void init224(LSH512_Context* ctx)
554 {
555  CRYPTOPP_ASSERT(ctx != NULLPTR);
556 
557  zero_submsgs(ctx);
558  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV224);
559 }
560 
561 inline void init256(LSH512_Context* ctx)
562 {
563  CRYPTOPP_ASSERT(ctx != NULLPTR);
564 
565  zero_submsgs(ctx);
566  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV256);
567 }
568 
569 inline void init384(LSH512_Context* ctx)
570 {
571  CRYPTOPP_ASSERT(ctx != NULLPTR);
572 
573  zero_submsgs(ctx);
574  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV384);
575 }
576 
577 inline void init512(LSH512_Context* ctx)
578 {
579  CRYPTOPP_ASSERT(ctx != NULLPTR);
580 
581  zero_submsgs(ctx);
582  load_iv(ctx->cv_l, ctx->cv_r, LSH512_IV512);
583 }
584 
585 /* -------------------------------------------------------- */
586 
587 inline void fin(LSH512_Context* ctx)
588 {
589  CRYPTOPP_ASSERT(ctx != NULLPTR);
590 
591  for (size_t i = 0; i < HASH_VAL_MAX_WORD_LEN; i++){
592  ctx->cv_l[i] = loadLE64(ctx->cv_l[i] ^ ctx->cv_r[i]);
593  }
594 }
595 
596 /* -------------------------------------------------------- */
597 
598 inline void get_hash(LSH512_Context* ctx, lsh_u8* pbHashVal)
599 {
600  CRYPTOPP_ASSERT(ctx != NULLPTR);
601  CRYPTOPP_ASSERT(ctx->alg_type != 0);
602  CRYPTOPP_ASSERT(pbHashVal != NULLPTR);
603 
604  lsh_uint alg_type = ctx->alg_type;
605  lsh_uint hash_val_byte_len = LSH_GET_HASHBYTE(alg_type);
606  lsh_uint hash_val_bit_len = LSH_GET_SMALL_HASHBIT(alg_type);
607 
608  // Multiplying by looks odd...
609  std::memcpy(pbHashVal, ctx->cv_l, hash_val_byte_len);
610  if (hash_val_bit_len){
611  pbHashVal[hash_val_byte_len-1] &= (((lsh_u8)0xff) << hash_val_bit_len);
612  }
613 }
614 
615 /* -------------------------------------------------------- */
616 
617 lsh_err lsh512_init(LSH512_Context* ctx)
618 {
619  CRYPTOPP_ASSERT(ctx != NULLPTR);
620  CRYPTOPP_ASSERT(ctx->alg_type != 0);
621 
622  lsh_u32 alg_type = ctx->alg_type;
623  const lsh_u64* const_v = NULL;
624  ctx->remain_databitlen = 0;
625 
626  switch (alg_type){
627  case LSH_TYPE_512_512:
628  init512(ctx);
629  return LSH_SUCCESS;
630  case LSH_TYPE_512_384:
631  init384(ctx);
632  return LSH_SUCCESS;
633  case LSH_TYPE_512_256:
634  init256(ctx);
635  return LSH_SUCCESS;
636  case LSH_TYPE_512_224:
637  init224(ctx);
638  return LSH_SUCCESS;
639  default:
640  break;
641  }
642 
643  lsh_u64* cv_l = ctx->cv_l;
644  lsh_u64* cv_r = ctx->cv_r;
645 
646  zero_iv(cv_l, cv_r);
647  cv_l[0] = LSH512_HASH_VAL_MAX_BYTE_LEN;
648  cv_l[1] = LSH_GET_HASHBIT(alg_type);
649 
650  for (size_t i = 0; i < NUM_STEPS / 2; i++)
651  {
652  //Mix
653  load_sc(&const_v, i * 16);
654  mix<ROT_EVEN_ALPHA, ROT_EVEN_BETA>(cv_l, cv_r, const_v);
655  word_perm(cv_l, cv_r);
656 
657  load_sc(&const_v, i * 16 + 8);
658  mix<ROT_ODD_ALPHA, ROT_ODD_BETA>(cv_l, cv_r, const_v);
659  word_perm(cv_l, cv_r);
660  }
661 
662  return LSH_SUCCESS;
663 }
664 
665 lsh_err lsh512_update(LSH512_Context* ctx, const lsh_u8* data, size_t databitlen)
666 {
667  CRYPTOPP_ASSERT(ctx != NULLPTR);
668  CRYPTOPP_ASSERT(data != NULLPTR);
669  CRYPTOPP_ASSERT(databitlen % 8 == 0);
670  CRYPTOPP_ASSERT(ctx->alg_type != 0);
671 
672  if (databitlen == 0){
673  return LSH_SUCCESS;
674  }
675 
676  // We are byte oriented. tail bits will always be 0.
677  size_t databytelen = databitlen >> 3;
678  // lsh_uint pos2 = databitlen & 0x7;
679  const size_t pos2 = 0;
680 
681  size_t remain_msg_byte = static_cast<size_t>(ctx->remain_databitlen >> 3);
682  // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7;
683  const size_t remain_msg_bit = 0;
684 
685  if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){
686  return LSH_ERR_INVALID_STATE;
687  }
688  if (remain_msg_bit > 0){
689  return LSH_ERR_INVALID_DATABITLEN;
690  }
691 
692  if (databytelen + remain_msg_byte < LSH512_MSG_BLK_BYTE_LEN){
693  std::memcpy(ctx->last_block + remain_msg_byte, data, databytelen);
694  ctx->remain_databitlen += (lsh_uint)databitlen;
695  remain_msg_byte += (lsh_uint)databytelen;
696  if (pos2){
697  ctx->last_block[remain_msg_byte] = data[databytelen] & ((0xff >> pos2) ^ 0xff);
698  }
699  return LSH_SUCCESS;
700  }
701 
702  if (remain_msg_byte > 0){
703  size_t more_byte = LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte;
704  std::memcpy(ctx->last_block + remain_msg_byte, data, more_byte);
705  compress(ctx, ctx->last_block);
706  data += more_byte;
707  databytelen -= more_byte;
708  remain_msg_byte = 0;
709  ctx->remain_databitlen = 0;
710  }
711 
712  while (databytelen >= LSH512_MSG_BLK_BYTE_LEN)
713  {
714  // This call to compress caused some trouble.
715  // The data pointer can become unaligned in the
716  // previous block.
717  compress(ctx, data);
718  data += LSH512_MSG_BLK_BYTE_LEN;
719  databytelen -= LSH512_MSG_BLK_BYTE_LEN;
720  }
721 
722  if (databytelen > 0){
723  std::memcpy(ctx->last_block, data, databytelen);
724  ctx->remain_databitlen = (lsh_uint)(databytelen << 3);
725  }
726 
727  if (pos2){
728  ctx->last_block[databytelen] = data[databytelen] & ((0xff >> pos2) ^ 0xff);
729  ctx->remain_databitlen += pos2;
730  }
731  return LSH_SUCCESS;
732 }
733 
734 lsh_err lsh512_final(LSH512_Context* ctx, lsh_u8* hashval)
735 {
736  CRYPTOPP_ASSERT(ctx != NULLPTR);
737  CRYPTOPP_ASSERT(hashval != NULLPTR);
738 
739  // We are byte oriented. tail bits will always be 0.
740  size_t remain_msg_byte = static_cast<size_t>(ctx->remain_databitlen >> 3);
741  // lsh_uint remain_msg_bit = ctx->remain_databitlen & 7;
742  const size_t remain_msg_bit = 0;
743 
744  if (remain_msg_byte >= LSH512_MSG_BLK_BYTE_LEN){
745  return LSH_ERR_INVALID_STATE;
746  }
747 
748  if (remain_msg_bit){
749  ctx->last_block[remain_msg_byte] |= (0x1 << (7 - remain_msg_bit));
750  }
751  else{
752  ctx->last_block[remain_msg_byte] = 0x80;
753  }
754  std::memset(ctx->last_block + remain_msg_byte + 1, 0, LSH512_MSG_BLK_BYTE_LEN - remain_msg_byte - 1);
755 
756  compress(ctx, ctx->last_block);
757 
758  fin(ctx);
759  get_hash(ctx, hashval);
760 
761  return LSH_SUCCESS;
762 }
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 {
783 #if defined(CRYPTOPP_ENABLE_64BIT_SSE)
784 #if defined(CRYPTOPP_AVX2_AVAILABLE)
785  if (HasAVX2())
786  return "AVX2";
787  else
788 #endif
789 #if defined(CRYPTOPP_SSSE3_AVAILABLE)
790  if (HasSSSE3())
791  return "SSSE3";
792  else
793 #endif
794 #endif // CRYPTOPP_ENABLE_64BIT_SSE
795 
796  return "C++";
797 }
798 
799 void LSH512_Base_Restart_CXX(word64* state)
800 {
801  state[RemainingBits] = 0;
802  LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
803  lsh_err err = lsh512_init(&ctx);
804 
805  if (err != LSH_SUCCESS)
806  throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_init failed");
807 }
808 
809 void LSH512_Base_Update_CXX(word64* state, const byte *input, size_t size)
810 {
811  LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
812  lsh_err err = lsh512_update(&ctx, input, 8*size);
813 
814  if (err != LSH_SUCCESS)
815  throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_update failed");
816 }
817 
818 void LSH512_Base_TruncatedFinal_CXX(word64* state, byte *hash, size_t)
819 {
820  LSH512_Context ctx(state, state[AlgorithmType], state[RemainingBits]);
821  lsh_err err = lsh512_final(&ctx, hash);
822 
823  if (err != LSH_SUCCESS)
824  throw Exception(Exception::OTHER_ERROR, "LSH512_Base: lsh512_final failed");
825 }
826 
827 
829 {
830 #if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
831  if (HasAVX2())
832  LSH512_Base_Restart_AVX2(m_state);
833  else
834 #endif
835 #if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
836  if (HasSSSE3())
837  LSH512_Base_Restart_SSSE3(m_state);
838  else
839 #endif
840 
841  LSH512_Base_Restart_CXX(m_state);
842 }
843 
844 void LSH512_Base::Update(const byte *input, size_t size)
845 {
846  CRYPTOPP_ASSERT(input != NULLPTR);
847  CRYPTOPP_ASSERT(size);
848 
849 #if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
850  if (HasAVX2())
851  LSH512_Base_Update_AVX2(m_state, input, size);
852  else
853 #endif
854 #if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
855  if (HasSSSE3())
856  LSH512_Base_Update_SSSE3(m_state, input, size);
857  else
858 #endif
859 
860  LSH512_Base_Update_CXX(m_state, input, size);
861 }
862 
863 void LSH512_Base::TruncatedFinal(byte *hash, size_t size)
864 {
865  CRYPTOPP_ASSERT(hash != NULLPTR);
866  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  byte fullHash[LSH512_HASH_VAL_MAX_BYTE_LEN];
872  bool copyOut = (size < DigestSize());
873 
874 #if defined(CRYPTOPP_AVX2_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
875  if (HasAVX2())
876  LSH512_Base_TruncatedFinal_AVX2(m_state, copyOut ? fullHash : hash, size);
877  else
878 #endif
879 #if defined(CRYPTOPP_SSSE3_AVAILABLE) && defined(CRYPTOPP_ENABLE_64BIT_SSE)
880  if (HasSSSE3())
881  LSH512_Base_TruncatedFinal_SSSE3(m_state, copyOut ? fullHash : hash, size);
882  else
883 #endif
884 
885  LSH512_Base_TruncatedFinal_CXX(m_state, copyOut ? fullHash : hash, size);
886 
887  if (copyOut)
888  std::memcpy(hash, fullHash, size);
889 
890  Restart();
891 }
892 
893 NAMESPACE_END
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:164
@ OTHER_ERROR
Some other error occurred not belonging to other categories.
Definition: cryptlib.h:182
Access a block of memory.
Definition: misc.h:2975
void Restart()
Restart the hash.
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: lsh.h:144
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
void Update(const byte *input, size_t size)
Updates a hash with additional input.
Library configuration file.
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:129
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:101
Functions for CPU features and intrinsics.
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:150
EnumToType< ByteOrder, LITTLE_ENDIAN_ORDER > LittleEndian
Provides a constant for LittleEndian.
Definition: cryptlib.h:155
Classes for the LSH hash functions.
Utility functions for the Crypto++ library.
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1757
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:2417
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1808
Crypto++ library namespace.
Precompiled header file.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68