aboutsummaryrefslogblamecommitdiffstats
path: root/misc-tests.c
blob: 4eca0a6e5a325c473c9ae606f51476b0ecf4941d (plain) (tree)
1
2
3
4
5
6
7
8
9
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672








                                                                                             
                         














                                                                         
                                       





































































































































































































































































































































































































































































































































































































































































                                                                                                                     
/* See LICENSE file for copyright and license details. */
#include "common.h"


#define ASSERT(ASSERTION)\
	do {\
		if ((ASSERTION))\
			break;\
		fprintf(stderr, "assertion `%s` at line %i failed\n", #ASSERTION, __LINE__);\
		exit(2);\
	} while (0)


static int
eq(struct libhashsum_hasher *a, struct libhashsum_hasher *b)
{
	if (a->algorithm != b->algorithm ||
	    !a->algorithm_string != !b->algorithm_string ||
	    a->input_block_size != b->input_block_size ||
	    a->hash_size != b->hash_size ||
	    !a->hash_output != !b->hash_output ||
	    a->supports_non_whole_bytes != b->supports_non_whole_bytes ||
	    a->process != b->process ||
	    a->finalise_const != b->finalise_const ||
	    a->finalise != b->finalise ||
	    a->stretch != b->stretch ||
	    a->destroy != b->destroy)
		return 0;
	if (a->hash_output && memcpy(a->hash_output, b->hash_output, a->hash_size))
		return 0;
	if (a->algorithm_string && strcmp(a->algorithm_string, b->algorithm_string))
		return 0;
	switch (a->algorithm) {
	case LIBHASHSUM_MD2:
	case LIBHASHSUM_MD4:
	case LIBHASHSUM_MD5:
	case LIBHASHSUM_RIPEMD_128:
	case LIBHASHSUM_RIPEMD_160:
	case LIBHASHSUM_RIPEMD_256:
	case LIBHASHSUM_RIPEMD_320:
	case LIBHASHSUM_SHA0:
	case LIBHASHSUM_SHA1:
	case LIBHASHSUM_SHA_224:
	case LIBHASHSUM_SHA_256:
	case LIBHASHSUM_SHA_384:
	case LIBHASHSUM_SHA_512:
	case LIBHASHSUM_SHA_512_224:
	case LIBHASHSUM_SHA_512_256:
	case LIBHASHSUM_BLAKE224:
	case LIBHASHSUM_BLAKE256:
	case LIBHASHSUM_BLAKE384:
	case LIBHASHSUM_BLAKE512:
		if (memcmp(&a->state, &b->state, sizeof(a->state)))
			return 0;
		break;
	case LIBHASHSUM_KECCAK:
	case LIBHASHSUM_KECCAK_224:
	case LIBHASHSUM_KECCAK_256:
	case LIBHASHSUM_KECCAK_384:
	case LIBHASHSUM_KECCAK_512:
	case LIBHASHSUM_SHA3_224:
	case LIBHASHSUM_SHA3_256:
	case LIBHASHSUM_SHA3_384:
	case LIBHASHSUM_SHA3_512:
	case LIBHASHSUM_SHAKE128:
	case LIBHASHSUM_SHAKE256:
	case LIBHASHSUM_SHAKE512:
	case LIBHASHSUM_RAWSHAKE128:
	case LIBHASHSUM_RAWSHAKE256:
	case LIBHASHSUM_RAWSHAKE512:
#ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE
		{
			unsigned char *aM, *bM;
			int r;
			if (a->state.keccak.squeezes != b->state.keccak.squeezes ||
			    a->state.keccak.suffix != b->state.keccak.suffix ||
			    !a->state.keccak.s.M != !b->state.keccak.s.M)
				return 0;
			aM = a->state.keccak.s.M;
			bM = b->state.keccak.s.M;
			a->state.keccak.s.M = NULL;
			b->state.keccak.s.M = NULL;
			r = memcmp(&a->state.keccak.s, &b->state.keccak.s, sizeof(a->state.keccak.s));
			a->state.keccak.s.M = aM;
			b->state.keccak.s.M = bM;
			if (r)
				return 0;
		}
		break;
#endif
	default:
		abort();
	}
	return 1;
}


static void
test_blake(const char *salt)
{
	struct libhashsum_hasher hasher1, hasher2, hasher3;
	int r;

	memset(&hasher1, 0xBC, sizeof(hasher1));
	memset(&hasher2, 0xBC, sizeof(hasher2));
	memset(&hasher3, 0xBC, sizeof(hasher3));
	errno = 0;
	r = libhashsum_init_blake224_hasher(&hasher1, salt);
	if (r) {
		ASSERT(r == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blakes_hasher(&hasher2, 224, salt) == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 16) == -1);
		ASSERT(errno == ENOSYS);
	} else {
		ASSERT(r == 0);
		ASSERT(libhashsum_init_blakes_hasher(&hasher2, 224, salt) == 0);
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 16) == 0);
		ASSERT(eq(&hasher1, &hasher2));
		ASSERT(eq(&hasher1, &hasher3));
		if (salt) {
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 0) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 8) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 17) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 32) == -1);
			ASSERT(errno == EINVAL);
		} else {
			memset(&hasher3, 0xBC, sizeof(hasher3));
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 0) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 8) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 17) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 224, salt, 32) == 0);
			ASSERT(eq(&hasher1, &hasher3));
		}
	}

	memset(&hasher1, 0xBC, sizeof(hasher1));
	memset(&hasher2, 0xBC, sizeof(hasher2));
	memset(&hasher3, 0xBC, sizeof(hasher3));
	errno = 0;
	r = libhashsum_init_blake256_hasher(&hasher1, salt);
	if (r) {
		ASSERT(r == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blakes_hasher(&hasher2, 256, salt) == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 16) == -1);
		ASSERT(errno == ENOSYS);
	} else {
		ASSERT(r == 0);
		ASSERT(libhashsum_init_blakes_hasher(&hasher2, 256, salt) == 0);
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 16) == 0);
		ASSERT(eq(&hasher1, &hasher2));
		ASSERT(eq(&hasher1, &hasher3));
		if (salt) {
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 0) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 8) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 17) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 32) == -1);
			ASSERT(errno == EINVAL);
		} else {
			memset(&hasher3, 0xBC, sizeof(hasher3));
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 0) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 8) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 17) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 256, salt, 32) == 0);
			ASSERT(eq(&hasher1, &hasher3));
		}
	}

	memset(&hasher1, 0xBC, sizeof(hasher1));
	memset(&hasher2, 0xBC, sizeof(hasher2));
	memset(&hasher3, 0xBC, sizeof(hasher3));
	errno = 0;
	r = libhashsum_init_blake384_hasher(&hasher1, salt);
	if (r) {
		ASSERT(r == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 384, salt) == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 32) == -1);
		ASSERT(errno == ENOSYS);
	} else {
		ASSERT(r == 0);
		ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 384, salt) == 0);
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 32) == 0);
		ASSERT(eq(&hasher1, &hasher2));
		ASSERT(eq(&hasher1, &hasher3));
		if (salt) {
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 0) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 16) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 33) == -1);
			ASSERT(errno == EINVAL);
		} else {
			memset(&hasher3, 0xBC, sizeof(hasher3));
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 0) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 16) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 384, salt, 33) == 0);
			ASSERT(eq(&hasher1, &hasher3));
		}
	}

	memset(&hasher1, 0xBC, sizeof(hasher1));
	memset(&hasher2, 0xBC, sizeof(hasher2));
	memset(&hasher3, 0xBC, sizeof(hasher3));
	errno = 0;
	r = libhashsum_init_blake512_hasher(&hasher1, salt);
	if (r) {
		ASSERT(r == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 512, salt) == -1);
		ASSERT(errno == ENOSYS);
		errno = 0;
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 32) == -1);
		ASSERT(errno == ENOSYS);
	} else {
		ASSERT(r == 0);
		ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 512, salt) == 0);
		ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 32) == 0);
		ASSERT(eq(&hasher1, &hasher2));
		ASSERT(eq(&hasher1, &hasher3));
		if (salt) {
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 0) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 16) == -1);
			ASSERT(errno == EINVAL);
			errno = 0;
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 33) == -1);
			ASSERT(errno == EINVAL);
		} else {
			memset(&hasher3, 0xBC, sizeof(hasher3));
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 0) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 16) == 0);
			ASSERT(libhashsum_init_blake_hasher(&hasher3, 512, salt, 33) == 0);
			ASSERT(eq(&hasher1, &hasher3));
		}
	}

#ifdef SUPPORT_BLAKES
	errno = 0;
	ASSERT(libhashsum_init_blakes_hasher(&hasher2, 128, salt) == -1);
	ASSERT(errno == EINVAL);
	errno = 0;
	ASSERT(libhashsum_init_blakes_hasher(&hasher2, 384, salt) == -1);
	ASSERT(errno == EINVAL);
#else
	errno = 0;
	ASSERT(libhashsum_init_blakes_hasher(&hasher2, 128, salt) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
	errno = 0;
	ASSERT(libhashsum_init_blakes_hasher(&hasher2, 384, salt) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
#endif

#ifdef SUPPORT_BLAKEB
	errno = 0;
	ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 128, salt) == -1);
	ASSERT(errno == EINVAL);
	errno = 0;
	ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 256, salt) == -1);
	ASSERT(errno == EINVAL);
	errno = 0;
	ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 1024, salt) == -1);
	ASSERT(errno == EINVAL);
#else
	errno = 0;
	ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 128, salt) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
	errno = 0;
	ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 256, salt) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
	errno = 0;
	ASSERT(libhashsum_init_blakeb_hasher(&hasher2, 1024, salt) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
#endif

#ifdef SUPPORT_BLAKE
	errno = 0;
	ASSERT(libhashsum_init_blake_hasher(&hasher2, 128, salt, 16) == -1);
	ASSERT(errno == EINVAL);
	errno = 0;
	ASSERT(libhashsum_init_blake_hasher(&hasher2, 400, salt, 32) == -1);
	ASSERT(errno == EINVAL);
	errno = 0;
	ASSERT(libhashsum_init_blake_hasher(&hasher2, 1024, salt, 32) == -1);
	ASSERT(errno == EINVAL);
#else
	errno = 0;
	ASSERT(libhashsum_init_blake_hasher(&hasher2, 128, salt, 16) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
	errno = 0;
	ASSERT(libhashsum_init_blake_hasher(&hasher2, 400, salt, 32) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
	errno = 0;
	ASSERT(libhashsum_init_blake_hasher(&hasher2, 1024, salt, 32) == -1);
	ASSERT(errno == EINVAL || errno == ENOSYS);
#endif
}


int
main(void)
{
	struct libhashsum_hasher hasher;
	enum libhashsum_algorithm algo;

	test_blake(NULL);
	test_blake("1234567890abcdefhijkABCDEFHIJK,.1234567890abcdefhijkABCDEFHIJK,.");

	errno = 0;
	ASSERT(libhashsum_init_hasher(&hasher, -1) == -1);
	ASSERT(errno == EINVAL);

	errno = 0;
	ASSERT(libhashsum_init_hasher(&hasher, 999) == -1);
	ASSERT(errno == EINVAL);

	errno = 0;
	ASSERT(libhashsum_init_hasher(&hasher, LIBHASHSUM_KECCAK) == -1);
	ASSERT(errno == EINVAL);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "X") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD55555") == 0);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD2") == 1 && algo == LIBHASHSUM_MD2);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD4") == 1 && algo == LIBHASHSUM_MD4);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD5") == 1 && algo == LIBHASHSUM_MD5);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak") == 1 && algo == LIBHASHSUM_KECCAK);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "md2") == 1 && algo == LIBHASHSUM_MD2);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "md4") == 1 && algo == LIBHASHSUM_MD4);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "md5") == 1 && algo == LIBHASHSUM_MD5);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "keccak") == 1 && algo == LIBHASHSUM_KECCAK);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "KECCAK") == 1 && algo == LIBHASHSUM_KECCAK);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD2[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD4[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "MD5[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak[]") == 1 && algo == LIBHASHSUM_KECCAK);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-128") == 1 && algo == LIBHASHSUM_RIPEMD_128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-160") == 1 && algo == LIBHASHSUM_RIPEMD_160);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-256") == 1 && algo == LIBHASHSUM_RIPEMD_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-320") == 1 && algo == LIBHASHSUM_RIPEMD_320);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-128") == 1 && algo == LIBHASHSUM_RIPEMD_128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-160") == 1 && algo == LIBHASHSUM_RIPEMD_160);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-256") == 1 && algo == LIBHASHSUM_RIPEMD_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-320") == 1 && algo == LIBHASHSUM_RIPEMD_320);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-0") == 1 && algo == LIBHASHSUM_SHA0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-1") == 1 && algo == LIBHASHSUM_SHA1);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-224") == 1 && algo == LIBHASHSUM_SHA_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-256") == 1 && algo == LIBHASHSUM_SHA_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-384") == 1 && algo == LIBHASHSUM_SHA_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512") == 1 && algo == LIBHASHSUM_SHA_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512/224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512/256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512-224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512-256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512_224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512_256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-224") == 1 && algo == LIBHASHSUM_SHA_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-256") == 1 && algo == LIBHASHSUM_SHA_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-384") == 1 && algo == LIBHASHSUM_SHA_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512") == 1 && algo == LIBHASHSUM_SHA_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512/224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512/256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512-224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512-256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512_224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512_256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-224") == 1 && algo == LIBHASHSUM_KECCAK_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-256") == 1 && algo == LIBHASHSUM_KECCAK_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-384") == 1 && algo == LIBHASHSUM_KECCAK_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-512") == 1 && algo == LIBHASHSUM_KECCAK_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-224") == 1 && algo == LIBHASHSUM_SHA3_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-256") == 1 && algo == LIBHASHSUM_SHA3_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-384") == 1 && algo == LIBHASHSUM_SHA3_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-512") == 1 && algo == LIBHASHSUM_SHA3_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE-128") == 1 && algo == LIBHASHSUM_SHAKE128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE-256") == 1 && algo == LIBHASHSUM_SHAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE-512") == 1 && algo == LIBHASHSUM_SHAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE-128") == 1 && algo == LIBHASHSUM_RAWSHAKE128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE-256") == 1 && algo == LIBHASHSUM_RAWSHAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE-512") == 1 && algo == LIBHASHSUM_RAWSHAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-224") == 1 && algo == LIBHASHSUM_BLAKE224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-256") == 1 && algo == LIBHASHSUM_BLAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-384") == 1 && algo == LIBHASHSUM_BLAKE384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-512") == 1 && algo == LIBHASHSUM_BLAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-224") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-256") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-384") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-512") == 0);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD128") == 1 && algo == LIBHASHSUM_RIPEMD_128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD160") == 1 && algo == LIBHASHSUM_RIPEMD_160);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD256") == 1 && algo == LIBHASHSUM_RIPEMD_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD320") == 1 && algo == LIBHASHSUM_RIPEMD_320);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD128") == 1 && algo == LIBHASHSUM_RIPEMD_128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD160") == 1 && algo == LIBHASHSUM_RIPEMD_160);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD256") == 1 && algo == LIBHASHSUM_RIPEMD_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD320") == 1 && algo == LIBHASHSUM_RIPEMD_320);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA0") == 1 && algo == LIBHASHSUM_SHA0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA1") == 1 && algo == LIBHASHSUM_SHA1);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-224") == 1 && algo == LIBHASHSUM_SHA_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-256") == 1 && algo == LIBHASHSUM_SHA_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-384") == 1 && algo == LIBHASHSUM_SHA_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512") == 1 && algo == LIBHASHSUM_SHA_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512/224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512/256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512-224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512-256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512_224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA2-512_256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA224") == 1 && algo == LIBHASHSUM_SHA_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA256") == 1 && algo == LIBHASHSUM_SHA_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA384") == 1 && algo == LIBHASHSUM_SHA_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512") == 1 && algo == LIBHASHSUM_SHA_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512/224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512/256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512-224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512-256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512_224") == 1 && algo == LIBHASHSUM_SHA_512_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA512_256") == 1 && algo == LIBHASHSUM_SHA_512_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak224") == 1 && algo == LIBHASHSUM_KECCAK_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak256") == 1 && algo == LIBHASHSUM_KECCAK_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak384") == 1 && algo == LIBHASHSUM_KECCAK_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak512") == 1 && algo == LIBHASHSUM_KECCAK_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA3-224") == 1 && algo == LIBHASHSUM_SHA3_224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA3-256") == 1 && algo == LIBHASHSUM_SHA3_256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA3-384") == 1 && algo == LIBHASHSUM_SHA3_384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA3-512") == 1 && algo == LIBHASHSUM_SHA3_512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE128") == 1 && algo == LIBHASHSUM_SHAKE128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE256") == 1 && algo == LIBHASHSUM_SHAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE512") == 1 && algo == LIBHASHSUM_SHAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE128") == 1 && algo == LIBHASHSUM_RAWSHAKE128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE256") == 1 && algo == LIBHASHSUM_RAWSHAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE512") == 1 && algo == LIBHASHSUM_RAWSHAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE224") == 1 && algo == LIBHASHSUM_BLAKE224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE256") == 1 && algo == LIBHASHSUM_BLAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE384") == 1 && algo == LIBHASHSUM_BLAKE384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE512") == 1 && algo == LIBHASHSUM_BLAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B224") == 1 && algo == LIBHASHSUM_BLAKE224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B256") == 1 && algo == LIBHASHSUM_BLAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B384") == 1 && algo == LIBHASHSUM_BLAKE384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B512") == 1 && algo == LIBHASHSUM_BLAKE512);

	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-128[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-160[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-320[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-128[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-160[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RMD-320[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-0[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-1[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-384[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512/224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512/256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512-224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512_224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-2-512_256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-384[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512/224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512/256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512-224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512_224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-512_256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-384[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "Keccak-512[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-224[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-256[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-384[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHA-3-512[]") == 0);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE-128[]") == 1 && algo == LIBHASHSUM_SHAKE128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE-256[]") == 1 && algo == LIBHASHSUM_SHAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "SHAKE-512[]") == 1 && algo == LIBHASHSUM_SHAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE-128[]") == 1 && algo == LIBHASHSUM_RAWSHAKE128);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE-256[]") == 1 && algo == LIBHASHSUM_RAWSHAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "RawSHAKE-512[]") == 1 && algo == LIBHASHSUM_RAWSHAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-224[]") == 1 && algo == LIBHASHSUM_BLAKE224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-256[]") == 1 && algo == LIBHASHSUM_BLAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-384[]") == 1 && algo == LIBHASHSUM_BLAKE384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-512[]") == 1 && algo == LIBHASHSUM_BLAKE512);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B224[]") == 1 && algo == LIBHASHSUM_BLAKE224);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B256[]") == 1 && algo == LIBHASHSUM_BLAKE256);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B384[]") == 1 && algo == LIBHASHSUM_BLAKE384);
	ASSERT(libhashsum_get_algorithm_from_string(&algo, "B512[]") == 1 && algo == LIBHASHSUM_BLAKE512);

#define CHECK(ALGO, CALL)\
	do {\
		struct libhashsum_hasher hasher2;\
		int r;\
		memset(&hasher, 0xBC, sizeof(hasher));\
		memset(&hasher2, 0xBC, sizeof(hasher2));\
		r = CALL;\
		if (r) {\
			ASSERT(r == -1);\
			ASSERT(errno == ENOSYS);\
			errno = 0;\
			ASSERT(libhashsum_init_hasher_from_string(&hasher2, ALGO) == -1);\
			ASSERT(errno == ENOSYS);\
			break;\
		}\
		ASSERT(libhashsum_init_hasher_from_string(&hasher2, ALGO) == 0);\
		ASSERT(eq(&hasher, &hasher2));\
		if (hasher.destroy) {\
			hasher.destroy(&hasher);\
			hasher2.destroy(&hasher2);\
		}\
	} while (0)

#define SALT "\x01\x23\x45\x67\x89\xAb\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"

	CHECK("MD2", libhashsum_init_md2_hasher(&hasher));
	CHECK("MD4", libhashsum_init_md4_hasher(&hasher));
	CHECK("MD5", libhashsum_init_md5_hasher(&hasher));
	CHECK("RIPEMD128", libhashsum_init_ripemd_128_hasher(&hasher));
	CHECK("RIPEMD160", libhashsum_init_ripemd_160_hasher(&hasher));
	CHECK("RIPEMD256", libhashsum_init_ripemd_256_hasher(&hasher));
	CHECK("RIPEMD320", libhashsum_init_ripemd_320_hasher(&hasher));
	CHECK("RMD128", libhashsum_init_ripemd_128_hasher(&hasher));
	CHECK("RMD160", libhashsum_init_ripemd_160_hasher(&hasher));
	CHECK("RMD256", libhashsum_init_ripemd_256_hasher(&hasher));
	CHECK("RMD320", libhashsum_init_ripemd_320_hasher(&hasher));
	CHECK("SHA0", libhashsum_init_sha0_hasher(&hasher));
	CHECK("SHA1", libhashsum_init_sha1_hasher(&hasher));
	CHECK("SHA2-224", libhashsum_init_sha_224_hasher(&hasher));
	CHECK("SHA2-256", libhashsum_init_sha_256_hasher(&hasher));
	CHECK("SHA2-384", libhashsum_init_sha_384_hasher(&hasher));
	CHECK("SHA2-512", libhashsum_init_sha_512_hasher(&hasher));
	CHECK("SHA2-512/224", libhashsum_init_sha_512_224_hasher(&hasher));
	CHECK("SHA2-512/256", libhashsum_init_sha_512_256_hasher(&hasher));
	CHECK("SHA2-512-224", libhashsum_init_sha_512_224_hasher(&hasher));
	CHECK("SHA2-512-256", libhashsum_init_sha_512_256_hasher(&hasher));
	CHECK("SHA2-512_224", libhashsum_init_sha_512_224_hasher(&hasher));
	CHECK("SHA2-512_256", libhashsum_init_sha_512_256_hasher(&hasher));
	CHECK("SHA224", libhashsum_init_sha_224_hasher(&hasher));
	CHECK("SHA256", libhashsum_init_sha_256_hasher(&hasher));
	CHECK("SHA384", libhashsum_init_sha_384_hasher(&hasher));
	CHECK("SHA512", libhashsum_init_sha_512_hasher(&hasher));
	CHECK("SHA512/224", libhashsum_init_sha_512_224_hasher(&hasher));
	CHECK("SHA512/256", libhashsum_init_sha_512_256_hasher(&hasher));
	CHECK("SHA512-224", libhashsum_init_sha_512_224_hasher(&hasher));
	CHECK("SHA512-256", libhashsum_init_sha_512_256_hasher(&hasher));
	CHECK("SHA512_224", libhashsum_init_sha_512_224_hasher(&hasher));
	CHECK("SHA512_256", libhashsum_init_sha_512_256_hasher(&hasher));
	CHECK("Keccak224", libhashsum_init_keccak_224_hasher(&hasher));
	CHECK("Keccak256", libhashsum_init_keccak_256_hasher(&hasher));
	CHECK("Keccak384", libhashsum_init_keccak_384_hasher(&hasher));
	CHECK("Keccak512", libhashsum_init_keccak_512_hasher(&hasher));
	CHECK("SHA3-224", libhashsum_init_sha3_224_hasher(&hasher));
	CHECK("SHA3-256", libhashsum_init_sha3_256_hasher(&hasher));
	CHECK("SHA3-384", libhashsum_init_sha3_384_hasher(&hasher));
	CHECK("SHA3-512", libhashsum_init_sha3_512_hasher(&hasher));
	CHECK("SHAKE128", libhashsum_init_shake128_hasher(&hasher, 0));
	CHECK("SHAKE256", libhashsum_init_shake256_hasher(&hasher, 0));
	CHECK("SHAKE512", libhashsum_init_shake512_hasher(&hasher, 0));
	CHECK("SHAKE128[]", libhashsum_init_shake128_hasher(&hasher, 0));
	CHECK("SHAKE256[]", libhashsum_init_shake256_hasher(&hasher, 0));
	CHECK("SHAKE512[]", libhashsum_init_shake512_hasher(&hasher, 0));
	CHECK("SHAKE128[n=10000]", libhashsum_init_shake128_hasher(&hasher, 10000));
	CHECK("SHAKE256[n=10000]", libhashsum_init_shake256_hasher(&hasher, 10000));
	CHECK("SHAKE512[N=10000]", libhashsum_init_shake512_hasher(&hasher, 10000));
	CHECK("RawSHAKE128", libhashsum_init_rawshake128_hasher(&hasher, 0));
	CHECK("RawSHAKE256", libhashsum_init_rawshake256_hasher(&hasher, 0));
	CHECK("RawSHAKE512", libhashsum_init_rawshake512_hasher(&hasher, 0));
	CHECK("RawSHAKE128[]", libhashsum_init_rawshake128_hasher(&hasher, 0));
	CHECK("RawSHAKE256[]", libhashsum_init_rawshake256_hasher(&hasher, 0));
	CHECK("RawSHAKE512[]", libhashsum_init_rawshake512_hasher(&hasher, 0));
	CHECK("RawSHAKE128[n=200]", libhashsum_init_rawshake128_hasher(&hasher, 200));
	CHECK("RawSHAKE256[N=200]", libhashsum_init_rawshake256_hasher(&hasher, 200));
	CHECK("RawSHAKE512[n=200]", libhashsum_init_rawshake512_hasher(&hasher, 200));
	CHECK("BLAKE224", libhashsum_init_blake224_hasher(&hasher, NULL));
	CHECK("BLAKE256", libhashsum_init_blake256_hasher(&hasher, NULL));
	CHECK("BLAKE384", libhashsum_init_blake384_hasher(&hasher, NULL));
	CHECK("BLAKE512", libhashsum_init_blake512_hasher(&hasher, NULL));
	CHECK("BLAKE224[]", libhashsum_init_blake224_hasher(&hasher, NULL));
	CHECK("BLAKE256[]", libhashsum_init_blake256_hasher(&hasher, NULL));
	CHECK("BLAKE384[]", libhashsum_init_blake384_hasher(&hasher, NULL));
	CHECK("BLAKE512[]", libhashsum_init_blake512_hasher(&hasher, NULL));
	CHECK("BLAKE224[salt=00000000000000000000000000000000]", libhashsum_init_blake224_hasher(&hasher, NULL));
	CHECK("BLAKE224[salt=0123456789abcdef0123456789ABCDEF]", libhashsum_init_blake224_hasher(&hasher, SALT));
	CHECK("BLAKE256[SALT=0123456789abcdef0123456789ABCDEF]", libhashsum_init_blake256_hasher(&hasher, SALT));
	CHECK("BLAKE384[Salt=0123456789abcdef0123456789abcdef0123456789ABCDEF0123456789ABCDEF]",
	      libhashsum_init_blake384_hasher(&hasher, SALT SALT));
	CHECK("BLAKE512[SaLt=0123456789abcdef0123456789abcdef0123456789ABCDEF0123456789ABCDEF]",
	      libhashsum_init_blake512_hasher(&hasher, SALT SALT));
	CHECK("BLAKE224[salt=0x0123456789Abcdef0123456789abcdef]", libhashsum_init_blake224_hasher(&hasher, SALT));
	CHECK("BLAKE256[SALT=0X0123456789aBcdef0123456789abcdef]", libhashsum_init_blake256_hasher(&hasher, SALT));
	CHECK("BLAKE384[Salt=0x0123456789abCdef0123456789abcdef0123456789abcdef0123456789abcdef]",
	      libhashsum_init_blake384_hasher(&hasher, SALT SALT));
	CHECK("BLAKE512[SaLt=0X0123456789abcDef0123456789abcdef0123456789abcdef0123456789abcdef]",
	      libhashsum_init_blake512_hasher(&hasher, SALT SALT));
	CHECK("Keccak", libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 0));
	CHECK("Keccak[r=256]", libhashsum_init_keccak_hasher(&hasher, 256, 0, 0, 0));
	CHECK("Keccak[R=256]", libhashsum_init_keccak_hasher(&hasher, 256, 0, 0, 0));
	CHECK("Keccak[c=256]", libhashsum_init_keccak_hasher(&hasher, 0, 256, 0, 0));
	CHECK("Keccak[C=256]", libhashsum_init_keccak_hasher(&hasher, 0, 256, 0, 0));
	CHECK("Keccak[n=256]", libhashsum_init_keccak_hasher(&hasher, 0, 0, 256, 0));
	CHECK("Keccak[N=256]", libhashsum_init_keccak_hasher(&hasher, 0, 0, 256, 0));
	CHECK("Keccak[z=256]", libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 256));
	CHECK("Keccak[Z=256]", libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 256));
	CHECK("Keccak[r=1200,c=400,n=100,z=60]", libhashsum_init_keccak_hasher(&hasher, 1200, 400, 100, 60));
	CHECK("Keccak[z=60,r=1200,c=400,n=100]", libhashsum_init_keccak_hasher(&hasher, 1200, 400, 100, 60));

#undef CHECK
#undef SALT

	ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=00000000]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=1234567890abcdef1234567890abcdef"
	                                                                 "1234567890abcdef1234567890abcdef]"));
	ASSERT(errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[n]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[n=]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[n=0]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[n=1000,]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[,n=1000]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "X") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[]sum") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[n=256]sum") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[r=0]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[c=0]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[n=0]") == -1 && errno == EINVAL);
	ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[z=0]") == -1 && errno == EINVAL);

	return 0;
}