Crypto++ 8.6 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;
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 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) {
254 return ConditionalByteReverse(LITTLE_ENDIAN_ORDER, 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
269 typedef GetBlock<word64, LittleEndian, false> InBlock;
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 memset(cv_l, 0, 8*sizeof(lsh_u64));
543 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 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 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 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 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 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 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
828 void LSH512_Base::Restart()
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 memcpy(hash, fullHash, size);
889
890 Restart();
891 }
892
893 NAMESPACE_END
LSH512_Base::Update
void Update(const byte *input, size_t size)
Updates a hash with additional input.
LSH512_Base::TruncatedFinal
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
W64LIT
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
byte
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:56
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
LITTLE_ENDIAN_ORDER
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:145
word64
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
rotlConstant
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1547
pch.h
Precompiled header file.
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
GetBlock
Access a block of memory.
Definition: misc.h:2528
Exception
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:158
misc.h
Utility functions for the Crypto++ library.
cpu.h
Functions for CPU features and intrinsics.
LSH512_Base::DigestSize
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: lsh.h:144
ConditionalByteReverse
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:2187
LittleEndian
EnumToType< ByteOrder, LITTLE_ENDIAN_ORDER > LittleEndian
Provides a constant for LittleEndian.
Definition: cryptlib.h:150
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
rotlFixed
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1598
LSH512_Base::Restart
void Restart()
Restart the hash.
Exception::OTHER_ERROR
@ OTHER_ERROR
Some other error occurred not belonging to other categories.
Definition: cryptlib.h:177
lsh.h
Classes for the LSH hash functions.
LSH512_Base::AlgorithmProvider
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.