1 /*
2  * -------------------------------------------------------------------------
3  * Works when compiled for either 32-bit or 64-bit targets, optimized for
4  * 64 bit.
5  *
6  * Canonical implementation of Init/Update/Finalize for SHA-3 byte input.
7  *
8  * SHA3-256, SHA3-384, SHA-512 are implemented. SHA-224 can easily be added.
9  *
10  * Based on code from http://keccak.noekeon.org/ .
11  *
12  * I place the code that I wrote into public domain, free to use.
13  *
14  * I would appreciate if you give credits to this work if you used it to
15  * write or test * your code.
16  *
17  * Aug 2015. Andrey Jivsov. crypto@brainhub.org
18  * ----------------------------------------------------------------------
19  */
20 module sha3iuf_d.sha3;
21 
22 
23 version (WebAssembly) {
24 } else {
25 	version = SHA3IUF_D_ENABLE_UNITTEST;
26 }
27 
28 /* 'Words' here refers to ulong */
29 ///
30 extern (C)
31 public enum SHA3_KECCAK_SPONGE_WORDS = (1600 / 8 /*bits to byte*/) / ulong.sizeof;
32 
33 ///
34 extern (C)
35 public struct sha3_context
36 {
37 	/*
38 	 * the portion of the input message that we
39 	 * didn't consume yet
40 	 */
41 	ulong saved;
42 
43 	union u_
44 	{
45 		/* Keccak's state */
46 		ulong[.SHA3_KECCAK_SPONGE_WORDS] s;
47 		ubyte[.SHA3_KECCAK_SPONGE_WORDS * 8] sb;
48 	}
49 
50 	u_ u;
51 
52 	/*
53 	 * 0..7--the next byte after the set one
54 	 * (starts from 0; 0--none are buffered)
55 	 */
56 	uint byteIndex;
57 
58 	/*
59 	 * 0..24--the next word to integrate input
60 	 * (starts from 0)
61 	 */
62 	uint wordIndex;
63 
64 	/*
65 	 * the double size of the hash output in
66 	 * words (e.g. 16 for Keccak 512)
67 	 */
68 	uint capacityWords;
69 }
70 
71 ///
72 extern (C)
73 public enum SHA3_FLAGS
74 {
75 	SHA3_FLAGS_NONE = 0,
76 	SHA3_FLAGS_KECCAK = 1,
77 }
78 
79 //Declaration name in C language
80 public enum
81 {
82 	SHA3_FLAGS_NONE = .SHA3_FLAGS.SHA3_FLAGS_NONE,
83 	SHA3_FLAGS_KECCAK = .SHA3_FLAGS.SHA3_FLAGS_KECCAK,
84 }
85 
86 ///
87 extern (C)
88 public enum SHA3_RETURN
89 {
90 	SHA3_RETURN_OK = 0,
91 	SHA3_RETURN_BAD_PARAMS = 1,
92 }
93 
94 //Declaration name in C language
95 public enum
96 {
97 	SHA3_RETURN_OK = .SHA3_RETURN.SHA3_RETURN_OK,
98 	SHA3_RETURN_BAD_PARAMS = .SHA3_RETURN.SHA3_RETURN_BAD_PARAMS,
99 }
100 
101 ///
102 public alias sha3_return_t = .SHA3_RETURN;
103 
104 //#define SHA3_TRACE(format, ...)
105 //#define SHA3_TRACE_BUF(format, buf, l)
106 
107 /*
108  * This flag is used to configure "pure" Keccak, as opposed to NIST SHA3.
109  */
110 private enum SHA3_USE_KECCAK_FLAG = 0x80000000;
111 
112 pragma(inline, true)
113 pure nothrow @safe @nogc @live
114 private ulong SHA3_CW(uint x)
115 
116 	do
117 	{
118 		return x & ~SHA3_USE_KECCAK_FLAG;
119 	}
120 
121 pragma(inline, true)
122 pure nothrow @safe @nogc @live
123 private ulong SHA3_ROTL64(ulong x, ulong y)
124 
125 	do
126 	{
127 		return (x << y) | (x >> ((ulong.sizeof * 8) - y));
128 	}
129 
130 private static immutable ulong[24] keccakf_rndc = [0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL, 0x8000000080008000UL, 0x000000000000808BUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL, 0x000000000000008AUL, 0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000AUL, 0x000000008000808BUL, 0x800000000000008BUL, 0x8000000000008089UL, 0x8000000000008003UL, 0x8000000000008002UL, 0x8000000000000080UL, 0x000000000000800AUL, 0x800000008000000AUL, 0x8000000080008081UL, 0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL];
131 
132 private static immutable uint[24] keccakf_rotc = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44];
133 
134 private static immutable uint[24] keccakf_piln = [10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1];
135 
136 /*
137  * generally called after SHA3_KECCAK_SPONGE_WORDS-ctx.capacityWords words
138  * are XORed into the state s
139  */
140 pure nothrow @safe @nogc @live
141 private void keccakf(ref ulong[25] s)
142 
143 	do
144 	{
145 		enum KECCAK_ROUNDS = 24;
146 		ulong t = void;
147 		ulong[5] bc = void;
148 
149 		for (size_t round = 0; round < KECCAK_ROUNDS; round++) {
150 			/* Theta */
151 			for (size_t i = 0; i < 5; i++) {
152 				bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
153 			}
154 
155 			for (size_t i = 0; i < 5; i++) {
156 				t = bc[(i + 4) % 5] ^ SHA3_ROTL64(bc[(i + 1) % 5], 1);
157 
158 				for (size_t j = 0; j < 25; j += 5) {
159 					s[j + i] ^= t;
160 				}
161 			}
162 
163 			/* Rho Pi */
164 			t = s[1];
165 
166 			for (size_t i = 0; i < 24; i++) {
167 				size_t j = keccakf_piln[i];
168 				bc[0] = s[j];
169 				s[j] = SHA3_ROTL64(t, keccakf_rotc[i]);
170 				t = bc[0];
171 			}
172 
173 			/* Chi */
174 			for (size_t j = 0; j < 25; j += 5) {
175 				for (size_t i = 0; i < 5; i++) {
176 					bc[i] = s[j + i];
177 				}
178 
179 				for (size_t i = 0; i < 5; i++) {
180 					s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
181 				}
182 			}
183 
184 			/* Iota */
185 			s[0] ^= keccakf_rndc[round];
186 		}
187 	}
188 
189 /* *************************** Public Inteface ************************ */
190 
191 /* For Init or Reset call these: */
192 ///
193 extern (C)
194 pure nothrow @trusted @nogc @live
195 public .sha3_return_t sha3_Init(scope void* priv, uint bitSize)
196 
197 	in
198 	{
199 		assert(priv != null);
200 	}
201 
202 	do
203 	{
204 		.sha3_context* ctx = cast(.sha3_context*)(priv);
205 
206 		if ((bitSize != 256) && (bitSize != 384) && (bitSize != 512)) {
207 			return .SHA3_RETURN.SHA3_RETURN_BAD_PARAMS;
208 		}
209 
210 		*ctx = (*ctx).init;
211 		ctx.capacityWords = 2 * bitSize / (8 * ulong.sizeof);
212 
213 		return .SHA3_RETURN.SHA3_RETURN_OK;
214 	}
215 
216 ///
217 extern (C)
218 pure nothrow @trusted @nogc @live
219 public void sha3_Init256(scope void* priv)
220 
221 	do
222 	{
223 		.sha3_Init(priv, 256);
224 	}
225 
226 ///
227 extern (C)
228 pure nothrow @trusted @nogc @live
229 public void sha3_Init384(scope void* priv)
230 
231 	do
232 	{
233 		.sha3_Init(priv, 384);
234 	}
235 
236 ///
237 extern (C)
238 pure nothrow @trusted @nogc @live
239 public void sha3_Init512(scope void* priv)
240 
241 	do
242 	{
243 		.sha3_Init(priv, 512);
244 	}
245 
246 ///
247 extern (C)
248 pure nothrow @trusted @nogc @live
249 public .SHA3_FLAGS sha3_SetFlags(scope void* priv, .SHA3_FLAGS flags)
250 
251 	in
252 	{
253 		assert(priv != null);
254 	}
255 
256 	do
257 	{
258 		.sha3_context* ctx = cast(.sha3_context*)(priv);
259 		flags &= .SHA3_FLAGS.SHA3_FLAGS_KECCAK;
260 		ctx.capacityWords |= (flags == .SHA3_FLAGS.SHA3_FLAGS_KECCAK) ? (SHA3_USE_KECCAK_FLAG) : (0);
261 
262 		return flags;
263 	}
264 
265 ///
266 extern (C)
267 pure nothrow @trusted @nogc @live
268 public void sha3_Update(scope void* priv, scope const void* bufIn, size_t len)
269 
270 	in
271 	{
272 		assert(priv != null);
273 		assert(bufIn != null);
274 
275 		.sha3_context* ctx = cast(.sha3_context*)(priv);
276 		assert(ctx.byteIndex < 8);
277 		assert(ctx.wordIndex < (ctx.u.s.sizeof / ctx.u.s[0].sizeof));
278 	}
279 
280 	do
281 	{
282 		.sha3_context* ctx = cast(.sha3_context*)(priv);
283 
284 		/* 0...7 -- how much is needed to have a word */
285 		uint old_tail = (8 - ctx.byteIndex) & 7;
286 
287 		const (ubyte)* buf = cast(const (ubyte)*)(bufIn);
288 
289 		//SHA3_TRACE_BUF("called to update with:", buf, len);
290 
291 		if (len < old_tail) {
292 			/*
293 			 * have no complete word or haven't started
294 			 * the word yet
295 			 */
296 			//SHA3_TRACE("because %d<%d, store it and return", cast(uint)(len), cast(uint)(old_tail));
297 
298 			/* endian-independent code follows: */
299 			while (len--) {
300 				ctx.saved |= cast(ulong)(*(buf++)) << ((ctx.byteIndex++) * 8);
301 			}
302 
303 			assert(ctx.byteIndex < 8);
304 
305 			return;
306 		}
307 
308 		if (old_tail != 0) { /* will have one word to process */
309 			//SHA3_TRACE("completing one word with %d bytes", cast(uint)(old_tail));
310 			/* endian-independent code follows: */
311 			len -= old_tail;
312 
313 			while (old_tail--) {
314 				ctx.saved |= cast(ulong)(*(buf++)) << ((ctx.byteIndex++) * 8);
315 			}
316 
317 			/* now ready to add saved to the sponge */
318 			ctx.u.s[ctx.wordIndex] ^= ctx.saved;
319 			assert(ctx.byteIndex == 8);
320 			ctx.byteIndex = 0;
321 			ctx.saved = 0;
322 
323 			if (++ctx.wordIndex == (.SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx.capacityWords))) {
324 				keccakf(ctx.u.s);
325 				ctx.wordIndex = 0;
326 			}
327 		}
328 
329 		/* now work in full words directly from input */
330 
331 		assert(ctx.byteIndex == 0);
332 
333 		size_t words = len / ulong.sizeof;
334 		uint tail = cast(uint)(len - (words * ulong.sizeof));
335 
336 		//SHA3_TRACE("have %d full words to process", cast(uint)(words));
337 
338 		for (size_t i = 0; i < words; i++, buf += ulong.sizeof) {
339 			const ulong t = cast(ulong)(buf[0]) | (cast(ulong)(buf[1]) << (8 * 1)) | (cast(ulong)(buf[2]) << (8 * 2)) | (cast(ulong)(buf[3]) << (8 * 3)) | (cast(ulong)(buf[4]) << (8 * 4)) | (cast(ulong)(buf[5]) << (8 * 5)) | (cast(ulong)(buf[6]) << (8 * 6)) | (cast(ulong)(buf[7]) << (8 * 7));
340 
341 			//#if defined(__x86_64__) || defined(__i386__)
342 			//	assert(core.stdc.string.memcmp(&t, buf, 8) == 0);
343 			//#endif
344 
345 			ctx.u.s[ctx.wordIndex] ^= t;
346 
347 			if (++ctx.wordIndex == (.SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx.capacityWords))) {
348 				keccakf(ctx.u.s);
349 				ctx.wordIndex = 0;
350 			}
351 		}
352 
353 		//SHA3_TRACE("have %d bytes left to process, save them", cast(uint)(tail));
354 
355 		/* finally, save the partial word */
356 		assert((ctx.byteIndex == 0) && (tail < 8));
357 
358 		while (tail--) {
359 			//SHA3_TRACE("Store byte %02x '%c'", *buf, *buf);
360 			ctx.saved |= cast(ulong)(*(buf++)) << ((ctx.byteIndex++) * 8);
361 		}
362 
363 		assert(ctx.byteIndex < 8);
364 		//SHA3_TRACE("Have saved=0x%016" PRIx64 " at the end", ctx.saved);
365 	}
366 
367 /**
368  * This is simply the 'update' with the padding block.
369  * The padding block is 0x01 || 0x00* || 0x80. First 0x01 and last 0x80
370  * bytes are always present, but they can be the same byte.
371  */
372 extern (C)
373 pure nothrow @trusted @nogc @live
374 public const (void)* sha3_Finalize(return scope void* priv)
375 
376 	in
377 	{
378 		assert(priv != null);
379 	}
380 
381 	do
382 	{
383 		.sha3_context* ctx = cast(.sha3_context*)(priv);
384 
385 		//SHA3_TRACE("called with %d bytes in the buffer", ctx.byteIndex);
386 
387 		/*
388 		 * Append 2-bit suffix 01, per SHA-3 spec. Instead of 1 for padding we
389 		 * use 1<<2 below. The 0x02 below corresponds to the suffix 01.
390 		 * Overall, we feed 0, then 1, and finally 1 to start padding. Without
391 		 * M || 01, we would simply use 1 to start padding.
392 		 */
393 
394 		ulong t = void;
395 
396 		if (ctx.capacityWords & SHA3_USE_KECCAK_FLAG) {
397 			/* Keccak version */
398 			t = cast(ulong)((cast(ulong)(1)) << (ctx.byteIndex * 8));
399 		} else {
400 			/* SHA3 version */
401 			t = cast(ulong)((cast(ulong)(0x02 | (1 << 2))) << ((ctx.byteIndex) * 8));
402 		}
403 
404 		ctx.u.s[ctx.wordIndex] ^= ctx.saved ^ t;
405 
406 		ctx.u.s[cast(size_t)(.SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx.capacityWords) - 1)] ^= 0x8000000000000000UL;
407 		keccakf(ctx.u.s);
408 
409 		/*
410 		 * Return first bytes of the ctx.s. This conversion is not needed for
411 		 * little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__)
412 		 * || !defined(__ORDER_LITTLE_ENDIAN__) || __BYTE_ORDER__!=__ORDER_LITTLE_ENDIAN__
413 		 *    ... the conversion below ...
414 		 * #endif
415 		 */
416 		{
417 			for (uint i = 0; i < .SHA3_KECCAK_SPONGE_WORDS; i++) {
418 				const uint t1 = cast(uint)(ctx.u.s[i]);
419 				const uint t2 = cast(uint)((ctx.u.s[i] >> 16) >> 16);
420 				ctx.u.sb[(i * 8) + 0] = cast(ubyte)(t1);
421 				ctx.u.sb[(i * 8) + 1] = cast(ubyte)(t1 >> 8);
422 				ctx.u.sb[(i * 8) + 2] = cast(ubyte)(t1 >> 16);
423 				ctx.u.sb[(i * 8) + 3] = cast(ubyte)(t1 >> 24);
424 				ctx.u.sb[(i * 8) + 4] = cast(ubyte)(t2);
425 				ctx.u.sb[(i * 8) + 5] = cast(ubyte)(t2 >> 8);
426 				ctx.u.sb[(i * 8) + 6] = cast(ubyte)(t2 >> 16);
427 				ctx.u.sb[(i * 8) + 7] = cast(ubyte)(t2 >> 24);
428 			}
429 		}
430 
431 		//SHA3_TRACE_BUF("Hash: (first 32 bytes)", ctx.u.sb, 256 / 8);
432 
433 		return &(ctx.u.sb[0]);
434 	}
435 
436 
437 
438 /* Single-call hashing */
439 /**
440  * ?
441  *
442  * Params:
443  *      bitSize = 256, 384, 512
444  *      flags = .SHA3_FLAGS.SHA3_FLAGS_NONE or .SHA3_FLAGS.SHA3_FLAGS_KECCAK
445  *      in_ = ?
446  *      inBytes = ?
447  *      out_ = ?
448  *      outBytes = up to bitSize / 8; truncation OK
449  *
450  * Returns: ?
451  */
452 extern (C)
453 pure nothrow @trusted @nogc @live
454 public .sha3_return_t sha3_HashBuffer(uint bitSize, .SHA3_FLAGS flags, scope const void* in_, size_t inBytes, return scope void* out_, uint outBytes)
455 
456 	in
457 	{
458 		assert(in_ != null);
459 		assert(out_ != null);
460 	}
461 
462 	do
463 	{
464 		.sha3_context c = void;
465 		.sha3_return_t err = .sha3_Init(&c, bitSize);
466 
467 		if (err != .SHA3_RETURN.SHA3_RETURN_OK) {
468 			return err;
469 		}
470 
471 		if (.sha3_SetFlags(&c, flags) != flags) {
472 			return .SHA3_RETURN.SHA3_RETURN_BAD_PARAMS;
473 		}
474 
475 		.sha3_Update(&c, in_, inBytes);
476 		const void* h = .sha3_Finalize(&c);
477 		uint out_length = bitSize / 8;
478 
479 		if (outBytes < out_length) {
480 			return .SHA3_RETURN.SHA3_RETURN_BAD_PARAMS;
481 		}
482 
483 		out_[0 .. out_length] = h[0 .. out_length];
484 
485 		return .SHA3_RETURN.SHA3_RETURN_OK;
486 	}
487 
488 /* *************************** Self Tests ************************ */
489 
490 /*
491  * There are two set of mutually exclusive tests, based on SHA3_USE_KECCAK,
492  * which is undefined in the production version.
493  *
494  * Known answer tests are from NIST SHA3 test vectors at
495  * http://csrc.nist.gov/groups/ST/toolkit/examples.html
496  *
497  * SHA3-256:
498  *   http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA3-256_Msg0.pdf
499  *   http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA3-256_1600.pdf
500  * SHA3-384:
501  *   http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA3-384_1600.pdf
502  * SHA3-512:
503  *   http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA3-512_1600.pdf
504  *
505  * These are refered to as [FIPS 202] tests.
506  *
507  * -----
508  *
509  * A few Keccak algorithm tests (when M and not M||01 is hashed) are
510  * added here. These are from http://keccak.noekeon.org/KeccakKAT-3.zip,
511  * ShortMsgKAT_256.txt for sizes even to 8. There is also one test for
512  * ExtremelyLongMsgKAT_256.txt.
513  *
514  * These will work with this code when SHA3_USE_KECCAK converts Finalize
515  * to use "pure" Keccak algorithm.
516  *
517  *
518  * These are referred to as [Keccak] test.
519  *
520  * -----
521  *
522  * In one case the input from [Keccak] test was used to test SHA3
523  * implementation. In this case the calculated hash was compared with
524  * the output of the sha3sum on Fedora Core 20 (which is Perl's based).
525  *
526  */
527 
528 version (SHA3IUF_D_ENABLE_UNITTEST)
529 unittest
530 {
531 	static import core.stdc.stdio;
532 	static import core.stdc.string;
533 
534 	/* [FIPS 202] KAT follow */
535 	static immutable ubyte[256 / 8] sha3_256_empty = [0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66, 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62, 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA, 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A];
536 	static immutable ubyte[256 / 8] sha3_256_0xa3_200_times = [0x79, 0xF3, 0x8A, 0xDE, 0xC5, 0xC2, 0x03, 0x07, 0xA9, 0x8E, 0xF7, 0x6E, 0x83, 0x24, 0xAF, 0xBF, 0xD4, 0x6C, 0xFD, 0x81, 0xB2, 0x2E, 0x39, 0x73, 0xC6, 0x5F, 0xA1, 0xBD, 0x9D, 0xE3, 0x17, 0x87];
537 	static immutable ubyte[384 / 8] sha3_384_0xa3_200_times = [0x18, 0x81, 0xDE, 0x2C, 0xA7, 0xE4, 0x1E, 0xF9, 0x5D, 0xC4, 0x73, 0x2B, 0x8F, 0x5F, 0x00, 0x2B, 0x18, 0x9C, 0xC1, 0xE4, 0x2B, 0x74, 0x16, 0x8E, 0xD1, 0x73, 0x26, 0x49, 0xCE, 0x1D, 0xBC, 0xDD, 0x76, 0x19, 0x7A, 0x31, 0xFD, 0x55, 0xEE, 0x98, 0x9F, 0x2D, 0x70, 0x50, 0xDD, 0x47, 0x3E, 0x8F];
538 	static immutable ubyte[512 / 8] sha3_512_0xa3_200_times = [0xE7, 0x6D, 0xFA, 0xD2, 0x20, 0x84, 0xA8, 0xB1, 0x46, 0x7F, 0xCF, 0x2F, 0xFA, 0x58, 0x36, 0x1B, 0xEC, 0x76, 0x28, 0xED, 0xF5, 0xF3, 0xFD, 0xC0, 0xE4, 0x80, 0x5D, 0xC4, 0x8C, 0xAE, 0xEC, 0xA8, 0x1B, 0x7C, 0x13, 0xC3, 0x0A, 0xDF, 0x52, 0xA3, 0x65, 0x95, 0x84, 0x73, 0x9A, 0x2D, 0xF4, 0x6B, 0xE5, 0x89, 0xC5, 0x1C, 0xA1, 0xA4, 0xA8, 0x41, 0x6D, 0xF6, 0x54, 0x5A, 0x1C, 0xE8, 0xBA, 0x00];
539 
540 	/* ---- "pure" Keccak algorithm begins; from [Keccak] ----- */
541 
542 	ubyte[200] buf = void;
543 	.sha3_HashBuffer(256, .SHA3_FLAGS.SHA3_FLAGS_KECCAK, &("abc\0"[0]), 3, &(buf[0]), buf.length);
544 
545 	assert(core.stdc..string.memcmp(&(buf[0]), &("\x4e\x03\x65\x7a\xea\x45\xa9\x4f\xc7\xd4\x7b\xa8\x26\xc8\xd6\x67\xc0\xd1\xe6\xe3\x3a\x64\xa0\x36\xec\x44\xf5\x8f\xa1\x2d\x6c\x45\0"[0]), 256 / 8) == 0, "SHA3-256(abc) doesn't match known answer (single buffer)\n");
546 
547 	.sha3_context c = void;
548 	const (ubyte)* hash = void;
549 
550 	{
551 		.sha3_Init256(&c);
552 		.sha3_SetFlags(&c, .SHA3_FLAGS.SHA3_FLAGS_KECCAK);
553 		.sha3_Update(&c, &("\xcc\0"[0]), 1);
554 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
555 
556 		assert(core.stdc..string.memcmp(hash, &("\xee\xad\x6d\xbf\xc7\x34\x0a\x56\xca\xed\xc0\x44\x69\x6a\x16\x88\x70\x54\x9a\x6a\x7f\x6f\x56\x96\x1e\x84\xa5\x4b\xd9\x97\x0b\x8a\0"[0]), 256 / 8) == 0, "SHA3-256(cc) doesn't match known answer (single buffer)\n");
557 	}
558 
559 	{
560 		.sha3_Init256(&c);
561 		.sha3_SetFlags(&c, .SHA3_FLAGS.SHA3_FLAGS_KECCAK);
562 		.sha3_Update(&c, &("\x41\xfb\0"[0]), 2);
563 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
564 
565 		assert(core.stdc..string.memcmp(hash, &("\xa8\xea\xce\xda\x4d\x47\xb3\x28\x1a\x79\x5a\xd9\xe1\xea\x21\x22\xb4\x07\xba\xf9\xaa\xbc\xb9\xe1\x8b\x57\x17\xb7\x87\x35\x37\xd2\0"[0]), 256 / 8) == 0, "SHA3-256(41fb) doesn't match known answer (single buffer)\n");
566 	}
567 
568 	{
569 		.sha3_Init256(&c);
570 		.sha3_SetFlags(&c, .SHA3_FLAGS.SHA3_FLAGS_KECCAK);
571 		.sha3_Update(&c, &("\x52\xa6\x08\xab\x21\xcc\xdd\x8a\x44\x57\xa5\x7e\xde\x78\x21\x76\0"[0]), 128 / 8);
572 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
573 
574 		assert(core.stdc..string.memcmp(hash, &("\x0e\x32\xde\xfa\x20\x71\xf0\xb5\xac\x0e\x6a\x10\x8b\x84\x2e\xd0\xf1\xd3\x24\x97\x12\xf5\x8e\xe0\xdd\xf9\x56\xfe\x33\x2a\x5f\x95\0"[0]), 256 / 8) == 0, "SHA3-256(52a6...76) doesn't match known answer (single buffer)\n");
575 	}
576 
577 	{
578 		.sha3_Init256(&c);
579 		.sha3_SetFlags(&c, .SHA3_FLAGS.SHA3_FLAGS_KECCAK);
580 		.sha3_Update(&c, &("\x43\x3c\x53\x03\x13\x16\x24\xc0\x02\x1d\x86\x8a\x30\x82\x54\x75\xe8\xd0\xbd\x30\x52\xa0\x22\x18\x03\x98\xf4\xca\x44\x23\xb9\x82\x14\xb6\xbe\xaa\xc2\x1c\x88\x07\xa2\xc3\x3f\x8c\x93\xbd\x42\xb0\x92\xcc\x1b\x06\xce\xdf\x32\x24\xd5\xed\x1e\xc2\x97\x84\x44\x4f\x22\xe0\x8a\x55\xaa\x58\x54\x2b\x52\x4b\x02\xcd\x3d\x5d\x5f\x69\x07\xaf\xe7\x1c\x5d\x74\x62\x22\x4a\x3f\x9d\x9e\x53\xe7\xe0\x84\x6d\xcb\xb4\xce\0"[0]), 800 / 8);
581 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
582 
583 		assert(core.stdc..string.memcmp(hash, &("\xce\x87\xa5\x17\x3b\xff\xd9\x23\x99\x22\x16\x58\xf8\x01\xd4\x5c\x29\x4d\x90\x06\xee\x9f\x3f\x9d\x41\x9c\x8d\x42\x77\x48\xdc\x41\0"[0]), 256 / 8) == 0, "SHA3-256(433C...CE) doesn't match known answer (single buffer)\n");
584 	}
585 
586 	/*
587 	 * SHA3-256 byte-by-byte: 16777216 steps. ExtremelyLongMsgKAT_256
588 	 * [Keccak]
589 	 */
590 	version (SHA3IUF_D_ALL_UNITTEST) {
591 		{
592 			uint i = 16777216;
593 			.sha3_Init256(&c);
594 			.sha3_SetFlags(&c, .SHA3_FLAGS.SHA3_FLAGS_KECCAK);
595 
596 			while (i--) {
597 				core.stdc.stdio.printf("%u\n", i);
598 				.sha3_Update(&c, &("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno\0"[0]), 64);
599 			}
600 
601 			hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
602 
603 			assert(core.stdc..string.memcmp(hash, &("\x5f\x31\x3c\x39\x96\x3d\xcf\x79\x2b\x54\x70\xd4\xad\xe9\xf3\xa3\x56\xa3\xe4\x02\x17\x48\x69\x0a\x95\x83\x72\xe2\xb0\x6f\x82\xa4\0"[0]), 256 / 8) == 0, "SHA3-256( abcdefgh...[16777216 times] ) doesn't match known answer\n");
604 
605 			core.stdc.stdio.printf("Keccak-256 tests passed OK\n");
606 		}
607 	}
608 
609 	/* ----- SHA3 testing begins ----- */
610 
611 	/* SHA-256 on an empty buffer */
612 	{
613 		.sha3_Init256(&c);
614 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
615 
616 		assert(core.stdc..string.memcmp(&(sha3_256_empty[0]), hash, sha3_256_empty.length) == 0, "SHA3-256() doesn't match known answer\n");
617 
618 		.sha3_HashBuffer(256, .SHA3_FLAGS.SHA3_FLAGS_NONE, &("abc\0"[0]), 3, &(buf[0]), buf.length);
619 
620 		assert(core.stdc..string.memcmp(&(buf[0]), &("\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32\0"[0]), 256 / 8) == 0, "SHA3-256(abc) doesn't match known answer (single buffer)\n");
621 	}
622 
623 	/* set to value c1 */
624 	const ubyte c1 = 0xA3;
625 	buf[] = c1;
626 
627 	/* SHA3-256 as a single buffer. [FIPS 202] */
628 	{
629 		.sha3_Init256(&c);
630 		.sha3_Update(&c, &(buf[0]), buf.length);
631 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
632 
633 		assert(core.stdc..string.memcmp(&(sha3_256_0xa3_200_times[0]), hash, sha3_256_0xa3_200_times.length) == 0, "SHA3-256( 0xA3 ... [200 times] ) doesn't match known answer (1 buffer)\n");
634 	}
635 
636 	/* SHA3-256 in two steps. [FIPS 202] */
637 	{
638 		.sha3_Init256(&c);
639 		.sha3_Update(&c, &(buf[0]), buf.length / 2);
640 		.sha3_Update(&c, &(buf[0]) + (buf.length / 2), buf.length / 2);
641 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
642 
643 		assert(core.stdc..string.memcmp(&(sha3_256_0xa3_200_times[0]), hash, sha3_256_0xa3_200_times.length) == 0, "SHA3-256( 0xA3 ... [200 times] ) doesn't match known answer (2 steps)\n");
644 	}
645 
646 	/* SHA3-256 byte-by-byte: 200 steps. [FIPS 202] */
647 	{
648 		uint i = 200;
649 		.sha3_Init256(&c);
650 
651 		while (i--) {
652 			.sha3_Update(&c, &c1, 1);
653 		}
654 
655 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
656 
657 		assert(core.stdc..string.memcmp(&(sha3_256_0xa3_200_times[0]), hash, sha3_256_0xa3_200_times.length) == 0, "SHA3-256( 0xA3 ... [200 times] ) doesn't match known answer (200 steps)\n");
658 	}
659 
660 	/*
661 	 * SHA3-256 byte-by-byte: 135 bytes. Input from [Keccak]. Output
662 	 * matched with sha3sum.
663 	 */
664 	{
665 		.sha3_Init256(&c);
666 		.sha3_Update(&c, &("\xb7\x71\xd5\xce\xf5\xd1\xa4\x1a\x93\xd1\x56\x43\xd7\x18\x1d\x2a\x2e\xf0\xa8\xe8\x4d\x91\x81\x2f\x20\xed\x21\xf1\x47\xbe\xf7\x32\xbf\x3a\x60\xef\x40\x67\xc3\x73\x4b\x85\xbc\x8c\xd4\x71\x78\x0f\x10\xdc\x9e\x82\x91\xb5\x83\x39\xa6\x77\xb9\x60\x21\x8f\x71\xe7\x93\xf2\x79\x7a\xea\x34\x94\x06\x51\x28\x29\x06\x5d\x37\xbb\x55\xea\x79\x6f\xa4\xf5\x6f\xd8\x89\x6b\x49\xb2\xcd\x19\xb4\x32\x15\xad\x96\x7c\x71\x2b\x24\xe5\x03\x2d\x06\x52\x32\xe0\x2c\x12\x74\x09\xd2\xed\x41\x46\xb9\xd7\x5d\x76\x3d\x52\xdb\x98\xd9\x49\xd3\xb0\xfe\xd6\xa8\x05\x2f\xbb\0"[0]), 1080 / 8);
667 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
668 
669 		assert(core.stdc..string.memcmp(hash, &("\xa1\x9e\xee\x92\xbb\x20\x97\xb6\x4e\x82\x3d\x59\x77\x98\xaa\x18\xbe\x9b\x7c\x73\x6b\x80\x59\xab\xfd\x67\x79\xac\x35\xac\x81\xb5\0"[0]), 256 / 8) == 0, "SHA3-256( b771 ... ) doesn't match the known answer\n");
670 	}
671 
672 	/* SHA3-384 as a single buffer. [FIPS 202] */
673 	{
674 		.sha3_Init384(&c);
675 		.sha3_Update(&c, &(buf[0]), buf.length);
676 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
677 
678 		assert(core.stdc..string.memcmp(&(sha3_384_0xa3_200_times[0]), hash, sha3_384_0xa3_200_times.length) == 0, "SHA3-384( 0xA3 ... [200 times] ) doesn't match known answer (1 buffer)\n");
679 	}
680 
681 	/* SHA3-384 in two steps. [FIPS 202] */
682 	{
683 		.sha3_Init384(&c);
684 		.sha3_Update(&c, &(buf[0]), buf.length / 2);
685 		.sha3_Update(&c, &(buf[0]) + (buf.length / 2), buf.length / 2);
686 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
687 
688 		assert(core.stdc..string.memcmp(&(sha3_384_0xa3_200_times[0]), hash, sha3_384_0xa3_200_times.length) == 0, "SHA3-384( 0xA3 ... [200 times] ) doesn't match known answer (2 steps)\n");
689 	}
690 
691 	/* SHA3-384 byte-by-byte: 200 steps. [FIPS 202] */
692 	{
693 		uint i = 200;
694 		.sha3_Init384(&c);
695 
696 		while (i--) {
697 			.sha3_Update(&c, &c1, 1);
698 		}
699 
700 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
701 
702 		assert(core.stdc..string.memcmp(&(sha3_384_0xa3_200_times[0]), hash, sha3_384_0xa3_200_times.length) == 0, "SHA3-384( 0xA3 ... [200 times] ) doesn't match known answer (200 steps)\n");
703 	}
704 
705 	/* SHA3-512 as a single buffer. [FIPS 202] */
706 	{
707 		.sha3_Init512(&c);
708 		.sha3_Update(&c, &(buf[0]), buf.length);
709 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
710 
711 		assert(core.stdc..string.memcmp(&(sha3_512_0xa3_200_times[0]), hash, sha3_512_0xa3_200_times.length) == 0, "SHA3-512( 0xA3 ... [200 times] ) doesn't match known answer (1 buffer)\n");
712 	}
713 
714 	/* SHA3-512 in two steps. [FIPS 202] */
715 	{
716 		.sha3_Init512(&c);
717 		.sha3_Update(&c, &(buf[0]), buf.length / 2);
718 		.sha3_Update(&c, &(buf[0]) + (buf.length / 2), buf.length / 2);
719 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
720 
721 		assert(core.stdc..string.memcmp(&(sha3_512_0xa3_200_times[0]), hash, sha3_512_0xa3_200_times.length) == 0, "SHA3-512( 0xA3 ... [200 times] ) doesn't match known answer (2 steps)\n");
722 	}
723 
724 	/* SHA3-512 byte-by-byte: 200 steps. [FIPS 202] */
725 	{
726 		uint i = 200;
727 		.sha3_Init512(&c);
728 
729 		while (i--) {
730 			.sha3_Update(&c, &c1, 1);
731 		}
732 
733 		hash = cast(const (ubyte)*)(.sha3_Finalize(&c));
734 
735 		assert(core.stdc..string.memcmp(&(sha3_512_0xa3_200_times[0]), hash, sha3_512_0xa3_200_times.length) == 0, "SHA3-512( 0xA3 ... [200 times] ) doesn't match known answer (200 steps)\n");
736 	}
737 
738 	core.stdc.stdio.printf("SHA3-256, SHA3-384, SHA3-512 tests passed OK\n");
739 }