1 /*
2  *  Chocobo1/Hash
3  *
4  *   Copyright 2018 by Mike Tzou (Chocobo1)
5  *     https://github.com/Chocobo1/Hash
6  *
7  *   Licensed under GNU General Public License 3 or later.
8  *
9  *  @license GPL3 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>
10  */
11 
12 #include "../src/sm3.h"
13 
14 #include "catch2/single_include/catch2/catch.hpp"
15 
16 #include <cstring>
17 
18 
19 #define ARRAY_LENGTH(a) (static_cast<int>(std::extent<decltype(a)>::value))
20 
21 
22 TEST_CASE("sm3")
23 {
24 	using Hash = Chocobo1::SM3;
25 
26 	// official test suite in rfc
27 	const char s1[] = "abc";
28 	REQUIRE("66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0" == Hash().addData(s1, strlen(s1)).finalize().toString());
29 
30 	const char s2[] = "abcd";
31 	Hash test2;
32 	for (long int i = 0 ; i < 16; ++i)
33 		test2.addData(s2, strlen(s2));
34 	REQUIRE("debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732" == test2.finalize().toString());
35 
36 	const char s3[] = "\x00\x90\x41\x4c\x49\x43\x45\x31\x32\x33\x40\x59\x41\x48\x4f\x4f"\
37 					  "\x2e\x43\x4f\x4d\x78\x79\x68\xb4\xfa\x32\xc3\xfd\x24\x17\x84\x2e"\
38 					  "\x73\xbb\xfe\xff\x2f\x3c\x84\x8b\x68\x31\xd7\xe0\xec\x65\x22\x8b"\
39 					  "\x39\x37\xe4\x98\x63\xe4\xc6\xd3\xb2\x3b\x0c\x84\x9c\xf8\x42\x41"\
40 					  "\x48\x4b\xfe\x48\xf6\x1d\x59\xa5\xb1\x6b\xa0\x6e\x6e\x12\xd1\xda"\
41 					  "\x27\xc5\x24\x9a\x42\x1d\xeb\xd6\x1b\x62\xea\xb6\x74\x64\x34\xeb"\
42 					  "\xc3\xcc\x31\x5e\x32\x22\x0b\x3b\xad\xd5\x0b\xdc\x4c\x4e\x6c\x14"\
43 					  "\x7f\xed\xd4\x3d\x06\x80\x51\x2b\xcb\xb4\x2c\x07\xd4\x73\x49\xd2"\
44 					  "\x15\x3b\x70\xc4\xe5\xd7\xfd\xfc\xbf\xa3\x6e\xa1\xa8\x58\x41\xb9"\
45 					  "\xe4\x6e\x09\xa2\x0a\xe4\xc7\x79\x8a\xa0\xf1\x19\x47\x1b\xee\x11"\
46 					  "\x82\x5b\xe4\x62\x02\xbb\x79\xe2\xa5\x84\x44\x95\xe9\x7c\x04\xff"\
47 					  "\x4d\xf2\x54\x8a\x7c\x02\x40\xf8\x8f\x1c\xd4\xe1\x63\x52\xa7\x3c"\
48 					  "\x17\xb7\xf1\x6f\x07\x35\x3e\x53\xa1\x76\xd6\x84\xa9\xfe\x0c\x6b"\
49 					  "\xb7\x98\xe8\x57";
50 	REQUIRE("f4a38489e32b45b6f876e3ac2168ca392362dc8f23459c1d1146fc3dbfb7bc9a" == Hash().addData(s3, (ARRAY_LENGTH(s3) - 1)).finalize().toString());
51 
52 	const char s4[] = "\xf4\xa3\x84\x89\xe3\x2b\x45\xb6\xf8\x76\xe3\xac\x21\x68\xca\x39" \
53 					  "\x23\x62\xdc\x8f\x23\x45\x9c\x1d\x11\x46\xfc\x3d\xbf\xb7\xbc\x9a" \
54 					  "\x6d\x65\x73\x73\x61\x67\x65\x20\x64\x69\x67\x65\x73\x74";
55 	REQUIRE("b524f552cd82b8b028476e005c377fb19a87e6fc682d48bb5d42e3d9b9effe76" == Hash().addData(s4, (ARRAY_LENGTH(s4) - 1)).finalize().toString());
56 
57 	const char s5[] = "\x00\x90\x41\x4c\x49\x43\x45\x31\x32\x33\x40\x59\x41\x48\x4f\x4f" \
58 					  "\x2e\x43\x4f\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
59 					  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
60 					  "\x00\x00\x00\x00\x00\x00\xe7\x8b\xcd\x09\x74\x6c\x20\x23\x78\xa7" \
61 					  "\xe7\x2b\x12\xbc\xe0\x02\x66\xb9\x62\x7e\xcb\x0b\x5a\x25\x36\x7a" \
62 					  "\xd1\xad\x4c\xc6\x24\x2b\x00\xcd\xb9\xca\x7f\x1e\x6b\x04\x41\xf6" \
63 					  "\x58\x34\x3f\x4b\x10\x29\x7c\x0e\xf9\xb6\x49\x10\x82\x40\x0a\x62" \
64 					  "\xe7\xa7\x48\x57\x35\xfa\xdd\x01\x3d\xe7\x4d\xa6\x59\x51\xc4\xd7" \
65 					  "\x6d\xc8\x92\x20\xd5\xf7\x77\x7a\x61\x1b\x1c\x38\xba\xe2\x60\xb1" \
66 					  "\x75\x95\x1d\xc8\x06\x0c\x2b\x3e\x01\x65\x96\x16\x45\x28\x1a\x86" \
67 					  "\x26\x60\x7b\x91\x7f\x65\x7d\x7e\x93\x82\xf1\xea\x5c\xd9\x31\xf4" \
68 					  "\x0f\x66\x27\xf3\x57\x54\x26\x53\xb2\x01\x68\x65\x22\x13\x0d\x59" \
69 					  "\x0f\xb8\xde\x63\x5d\x8f\xca\x71\x5c\xc6\xbf\x3d\x05\xbe\xf3\xf7" \
70 					  "\x5d\xa5\xd5\x43\x45\x44\x48\x16\x66\x12";
71 	REQUIRE("26352af82ec19f207bbc6f9474e11e90ce0f7ddace03b27f801817e897a81fd5" == Hash().addData(s5, (ARRAY_LENGTH(s5) - 1)).finalize().toString());
72 
73 	const char s6[] = "\x26\x35\x2a\xf8\x2e\xc1\x9f\x20\x7b\xbc\x6f\x94\x74\xe1\x1e\x90" \
74 					  "\xce\x0f\x7d\xda\xce\x03\xb2\x7f\x80\x18\x17\xe8\x97\xa8\x1f\xd5" \
75 					  "\x6d\x65\x73\x73\x61\x67\x65\x20\x64\x69\x67\x65\x73\x74";
76 	REQUIRE("ad673cbda311417129a9eaa5f9ab1aa1633ad47718a84dfd46c17c6fa0aa3b12" == Hash().addData(s6, (ARRAY_LENGTH(s6) - 1)).finalize().toString());
77 
78 	const char s7[] = "\x00\x90\x41\x4c\x49\x43\x45\x31\x32\x33\x40\x59\x41\x48\x4f\x4f" \
79 					  "\x2e\x43\x4f\x4d\x78\x79\x68\xb4\xfa\x32\xc3\xfd\x24\x17\x84\x2e" \
80 					  "\x73\xbb\xfe\xff\x2f\x3c\x84\x8b\x68\x31\xd7\xe0\xec\x65\x22\x8b" \
81 					  "\x39\x37\xe4\x98\x63\xe4\xc6\xd3\xb2\x3b\x0c\x84\x9c\xf8\x42\x41" \
82 					  "\x48\x4b\xfe\x48\xf6\x1d\x59\xa5\xb1\x6b\xa0\x6e\x6e\x12\xd1\xda" \
83 					  "\x27\xc5\x24\x9a\x42\x1d\xeb\xd6\x1b\x62\xea\xb6\x74\x64\x34\xeb" \
84 					  "\xc3\xcc\x31\x5e\x32\x22\x0b\x3b\xad\xd5\x0b\xdc\x4c\x4e\x6c\x14" \
85 					  "\x7f\xed\xd4\x3d\x06\x80\x51\x2b\xcb\xb4\x2c\x07\xd4\x73\x49\xd2" \
86 					  "\x15\x3b\x70\xc4\xe5\xd7\xfd\xfc\xbf\xa3\x6e\xa1\xa8\x58\x41\xb9" \
87 					  "\xe4\x6e\x09\xa2\x30\x99\x09\x3b\xf3\xc1\x37\xd8\xfc\xbb\xcd\xf4" \
88 					  "\xa2\xae\x50\xf3\xb0\xf2\x16\xc3\x12\x2d\x79\x42\x5f\xe0\x3a\x45" \
89 					  "\xdb\xfe\x16\x55\x3d\xf7\x9e\x8d\xac\x1c\xf0\xec\xba\xa2\xf2\xb4" \
90 					  "\x9d\x51\xa4\xb3\x87\xf2\xef\xaf\x48\x23\x39\x08\x6a\x27\xa8\xe0" \
91 					  "\x5b\xae\xd9\x8b";
92 	REQUIRE("e4d1d0c3ca4c7f11bc8ff8cb3f4c02a78f108fa098e51a668487240f75e20f31" == Hash().addData(s7, (ARRAY_LENGTH(s7) - 1)).finalize().toString());
93 
94 	const char s8[] = "\x00\x88\x42\x49\x4c\x4c\x34\x35\x36\x40\x59\x41\x48\x4f\x4f\x2e" \
95 					  "\x43\x4f\x4d\x78\x79\x68\xb4\xfa\x32\xc3\xfd\x24\x17\x84\x2e\x73" \
96 					  "\xbb\xfe\xff\x2f\x3c\x84\x8b\x68\x31\xd7\xe0\xec\x65\x22\x8b\x39" \
97 					  "\x37\xe4\x98\x63\xe4\xc6\xd3\xb2\x3b\x0c\x84\x9c\xf8\x42\x41\x48" \
98 					  "\x4b\xfe\x48\xf6\x1d\x59\xa5\xb1\x6b\xa0\x6e\x6e\x12\xd1\xda\x27" \
99 					  "\xc5\x24\x9a\x42\x1d\xeb\xd6\x1b\x62\xea\xb6\x74\x64\x34\xeb\xc3" \
100 					  "\xcc\x31\x5e\x32\x22\x0b\x3b\xad\xd5\x0b\xdc\x4c\x4e\x6c\x14\x7f" \
101 					  "\xed\xd4\x3d\x06\x80\x51\x2b\xcb\xb4\x2c\x07\xd4\x73\x49\xd2\x15" \
102 					  "\x3b\x70\xc4\xe5\xd7\xfd\xfc\xbf\xa3\x6e\xa1\xa8\x58\x41\xb9\xe4" \
103 					  "\x6e\x09\xa2\x24\x54\x93\xd4\x46\xc3\x8d\x8c\xc0\xf1\x18\x37\x46" \
104 					  "\x90\xe7\xdf\x63\x3a\x8a\x4b\xfb\x33\x29\xb5\xec\xe6\x04\xb2\xb4" \
105 					  "\xf3\x7f\x43\x53\xc0\x86\x9f\x4b\x9e\x17\x77\x3d\xe6\x8f\xec\x45" \
106 					  "\xe1\x49\x04\xe0\xde\xa4\x5b\xf6\xce\xcf\x99\x18\xc8\x5e\xa0\x47" \
107 					  "\xc6\x0a\x4c";
108 	REQUIRE("6b4b6d0e276691bd4a11bf72f4fb501ae309fdacb72fa6cc336e6656119abd67" == Hash().addData(s8, (ARRAY_LENGTH(s8) - 1)).finalize().toString());
109 
110 	const char s9[] = "\x47\xc8\x26\x53\x4d\xc2\xf6\xf1\xfb\xf2\x87\x28\xdd\x65\x8f\x21" \
111 					  "\xe1\x74\xf4\x81\x79\xac\xef\x29\x00\xf8\xb7\xf5\x66\xe4\x09\x05" \
112 					  "\xe4\xd1\xd0\xc3\xca\x4c\x7f\x11\xbc\x8f\xf8\xcb\x3f\x4c\x02\xa7" \
113 					  "\x8f\x10\x8f\xa0\x98\xe5\x1a\x66\x84\x87\x24\x0f\x75\xe2\x0f\x31" \
114 					  "\x6b\x4b\x6d\x0e\x27\x66\x91\xbd\x4a\x11\xbf\x72\xf4\xfb\x50\x1a" \
115 					  "\xe3\x09\xfd\xac\xb7\x2f\xa6\xcc\x33\x6e\x66\x56\x11\x9a\xbd\x67" \
116 					  "\x6c\xb5\x63\x38\x16\xf4\xdd\x56\x0b\x1d\xec\x45\x83\x10\xcb\xcc" \
117 					  "\x68\x56\xc0\x95\x05\x32\x4a\x6d\x23\x15\x0c\x40\x8f\x16\x2b\xf0" \
118 					  "\x0d\x6f\xcf\x62\xf1\x03\x6c\x0a\x1b\x6d\xac\xcf\x57\x39\x92\x23" \
119 					  "\xa6\x5f\x7d\x7b\xf2\xd9\x63\x7e\x5b\xbb\xeb\x85\x79\x61\xbf\x1a" \
120 					  "\x17\x99\xb2\xa2\xc7\x78\x29\x53\x00\xd9\xa2\x32\x5c\x68\x61\x29" \
121 					  "\xb8\xf2\xb5\x33\x7b\x3d\xcf\x45\x14\xe8\xbb\xc1\x9d\x90\x0e\xe5" \
122 					  "\x54\xc9\x28\x8c\x82\x73\x3e\xfd\xf7\x80\x8a\xe7\xf2\x7d\x0e\x73" \
123 					  "\x2f\x7c\x73\xa7\xd9\xac\x98\xb7\xd8\x74\x0a\x91\xd0\xdb\x3c\xf4";
124 	REQUIRE("ff49d95bd45fce99ed54a8ad7a7091109f51394442916bd154d1de4379d97647" == Hash().addData(s9, (ARRAY_LENGTH(s9) - 1)).finalize().toString());
125 
126 	const char s10[] = "\x02\x2a\xf8\x6e\xfe\x73\x2c\xf1\x2a\xd0\xe0\x9a\x1f\x25\x56\xcc" \
127 					   "\x65\x0d\x9c\xcc\xe3\xe2\x49\x86\x6b\xbb\x5c\x68\x46\xa4\xc4\xa2" \
128 					   "\x95\xff\x49\xd9\x5b\xd4\x5f\xce\x99\xed\x54\xa8\xad\x7a\x70\x91" \
129 					   "\x10\x9f\x51\x39\x44\x42\x91\x6b\xd1\x54\xd1\xde\x43\x79\xd9\x76" \
130 					   "\x47";
131 	REQUIRE("284c8f198f141b502e81250f1581c7e9eeb4ca6990f9e02df388b45471f5bc5c" == Hash().addData(s10, (ARRAY_LENGTH(s10) - 1)).finalize().toString());
132 
133 	const char s11[] = "\x03\x2a\xf8\x6e\xfe\x73\x2c\xf1\x2a\xd0\xe0\x9a\x1f\x25\x56\xcc" \
134 					   "\x65\x0d\x9c\xcc\xe3\xe2\x49\x86\x6b\xbb\x5c\x68\x46\xa4\xc4\xa2" \
135 					   "\x95\xff\x49\xd9\x5b\xd4\x5f\xce\x99\xed\x54\xa8\xad\x7a\x70\x91" \
136 					   "\x10\x9f\x51\x39\x44\x42\x91\x6b\xd1\x54\xd1\xde\x43\x79\xd9\x76" \
137 					   "\x47";
138 	REQUIRE("23444daf8ed7534366cb901c84b3bdbb63504f4065c1116c91a4c00697e6cf7a" == Hash().addData(s11, (ARRAY_LENGTH(s11) - 1)).finalize().toString());
139 
140 	const char s12[] = "\x00\x90\x41\x4c\x49\x43\x45\x31\x32\x33\x40\x59\x41\x48\x4f\x4f" \
141 					   "\x2e\x43\x4f\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
142 					   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
143 					   "\x00\x00\x00\x00\x00\x00\xe7\x8b\xcd\x09\x74\x6c\x20\x23\x78\xa7" \
144 					   "\xe7\x2b\x12\xbc\xe0\x02\x66\xb9\x62\x7e\xcb\x0b\x5a\x25\x36\x7a" \
145 					   "\xd1\xad\x4c\xc6\x24\x2b\x00\xcd\xb9\xca\x7f\x1e\x6b\x04\x41\xf6" \
146 					   "\x58\x34\x3f\x4b\x10\x29\x7c\x0e\xf9\xb6\x49\x10\x82\x40\x0a\x62" \
147 					   "\xe7\xa7\x48\x57\x35\xfa\xdd\x01\x3d\xe7\x4d\xa6\x59\x51\xc4\xd7" \
148 					   "\x6d\xc8\x92\x20\xd5\xf7\x77\x7a\x61\x1b\x1c\x38\xba\xe2\x60\xb1" \
149 					   "\x75\x95\x1d\xc8\x06\x0c\x2b\x3e\x00\x00\x00\x00\x00\x11\xf9\x19" \
150 					   "\x33\x88\xf1\xf9\x01\xcc\xc8\x57\xbf\x49\xcf\xc0\x65\xfb\x38\xb9" \
151 					   "\x06\x9c\xaa\xe6\xd5\xaf\xc3\x59\x2f\x00\x45\x55\x12\x2a\xac\x00" \
152 					   "\x75\xf4\x2e\x0a\x8b\xbd\x2c\x06\x65\xc7\x89\x12\x0d\xf1\x9d\x77" \
153 					   "\xb4\xe3\xee\x47\x12\xf5\x98\x04\x04\x15";
154 	REQUIRE("ecf0080215977b2e5d6d61b98a99442f03e8803dc39e349f8dca5621a9acdf2b" == Hash().addData(s12, (ARRAY_LENGTH(s12) - 1)).finalize().toString());
155 
156 	const char s13[] = "\x00\x90\x41\x4c\x49\x43\x45\x31\x32\x33\x40\x59\x41\x48\x4f\x4f" \
157 					   "\x2e\x43\x4f\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
158 					   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
159 					   "\x00\x00\x00\x00\x00\x00\xe7\x8b\xcd\x09\x74\x6c\x20\x23\x78\xa7" \
160 					   "\xe7\x2b\x12\xbc\xe0\x02\x66\xb9\x62\x7e\xcb\x0b\x5a\x25\x36\x7a" \
161 					   "\xd1\xad\x4c\xc6\x24\x2b\x00\xcd\xb9\xca\x7f\x1e\x6b\x04\x41\xf6" \
162 					   "\x58\x34\x3f\x4b\x10\x29\x7c\x0e\xf9\xb6\x49\x10\x82\x40\x0a\x62" \
163 					   "\xe7\xa7\x48\x57\x35\xfa\xdd\x01\x3d\xe7\x4d\xa6\x59\x51\xc4\xd7" \
164 					   "\x6d\xc8\x92\x20\xd5\xf7\x77\x7a\x61\x1b\x1c\x38\xba\xe2\x60\xb1" \
165 					   "\x75\x95\x1d\xc8\x06\x0c\x2b\x3e\x00\x00\x00\x00\x00\x11\xf9\x19" \
166 					   "\x33\x88\xf1\xf9\x01\xcc\xc8\x57\xbf\x49\xcf\xc0\x65\xfb\x38\xb9" \
167 					   "\x06\x9c\xaa\xe6\xd5\xaf\xc3\x59\x2f\x00\x45\x55\x12\x2a\xac\x00" \
168 					   "\x75\xf4\x2e\x0a\x8b\xbd\x2c\x06\x65\xc7\x89\x12\x0d\xf1\x9d\x77" \
169 					   "\xb4\xe3\xee\x47\x12\xf5\x98\x04\x04\x15";
170 	REQUIRE("ecf0080215977b2e5d6d61b98a99442f03e8803dc39e349f8dca5621a9acdf2b" == Hash().addData(s13, (ARRAY_LENGTH(s13) - 1)).finalize().toString());
171 
172 	const char s14[] = "\x00\x88\x42\x49\x4c\x4c\x34\x35\x36\x40\x59\x41\x48\x4f\x4f\x2e" \
173 					   "\x43\x4f\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
174 					   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
175 					   "\x00\x00\x00\x00\x00\xe7\x8b\xcd\x09\x74\x6c\x20\x23\x78\xa7\xe7" \
176 					   "\x2b\x12\xbc\xe0\x02\x66\xb9\x62\x7e\xcb\x0b\x5a\x25\x36\x7a\xd1" \
177 					   "\xad\x4c\xc6\x24\x2b\x00\xcd\xb9\xca\x7f\x1e\x6b\x04\x41\xf6\x58" \
178 					   "\x34\x3f\x4b\x10\x29\x7c\x0e\xf9\xb6\x49\x10\x82\x40\x0a\x62\xe7" \
179 					   "\xa7\x48\x57\x35\xfa\xdd\x01\x3d\xe7\x4d\xa6\x59\x51\xc4\xd7\x6d" \
180 					   "\xc8\x92\x20\xd5\xf7\x77\x7a\x61\x1b\x1c\x38\xba\xe2\x60\xb1\x75" \
181 					   "\x95\x1d\xc8\x06\x0c\x2b\x3e\x00\x34\x29\x7d\xd8\x3a\xb1\x4d\x5b" \
182 					   "\x39\x3b\x67\x12\xf3\x2b\x2f\x2e\x93\x8d\x46\x90\xb0\x95\x42\x4b" \
183 					   "\x89\xda\x88\x0c\x52\xd4\xa7\xd9\x01\x99\xbb\xf1\x1a\xc9\x5a\x0e" \
184 					   "\xa3\x4b\xbd\x00\xca\x50\xb9\x3e\xc2\x4a\xcb\x68\x33\x5d\x20\xba" \
185 					   "\x5d\xcf\xe3\xb3\x3b\xdb\xd2\xb6\x2d";
186 	REQUIRE("557bad30e183559aeec3b2256e1c7c11f870d22b165d015acf9465b09b87b527" == Hash().addData(s14, (ARRAY_LENGTH(s14) - 1)).finalize().toString());
187 
188 	const char s15[] = "\x00\xda\xdd\x08\x74\x06\x22\x1d\x65\x7b\xc3\xfa\x79\xff\x32\x9b" \
189 					   "\xb0\x22\xe9\xcb\x7d\xdf\xcf\xcc\xfe\x27\x7b\xe8\xcd\x4a\xe9\xb9" \
190 					   "\x54\xec\xf0\x08\x02\x15\x97\x7b\x2e\x5d\x6d\x61\xb9\x8a\x99\x44" \
191 					   "\x2f\x03\xe8\x80\x3d\xc3\x9e\x34\x9f\x8d\xca\x56\x21\xa9\xac\xdf" \
192 					   "\x2b\x55\x7b\xad\x30\xe1\x83\x55\x9a\xee\xc3\xb2\x25\x6e\x1c\x7c" \
193 					   "\x11\xf8\x70\xd2\x2b\x16\x5d\x01\x5a\xcf\x94\x65\xb0\x9b\x87\xb5" \
194 					   "\x27\x01\x81\x07\x65\x43\xed\x19\x05\x8c\x38\xb3\x13\xd7\x39\x92" \
195 					   "\x1d\x46\xb8\x00\x94\xd9\x61\xa1\x36\x73\xd4\xa5\xcf\x8c\x71\x59" \
196 					   "\xe3\x04\x01\xd8\xcf\xff\x7c\xa2\x7a\x01\xa2\xe8\x8c\x18\x67\x37" \
197 					   "\x48\xfd\xe9\xa7\x4c\x1f\x9b\x45\x64\x6e\xca\x09\x97\x29\x3c\x15" \
198 					   "\xc3\x4d\xd8\x00\x2a\x48\x32\xb4\xdc\xd3\x99\xba\xab\x3f\xff\xe7" \
199 					   "\xdd\x6c\xe6\xed\x68\xcc\x43\xff\xa5\xf2\x62\x3b\x9b\xd0\x4e\x46" \
200 					   "\x8d\x32\x2a\x2a\x00\x16\x59\x9b\xb5\x2e\xd9\xea\xfa\xd0\x1c\xfa" \
201 					   "\x45\x3c\xf3\x05\x2e\xd6\x01\x84\xd2\xee\xcf\xd4\x2b\x52\xdb\x74" \
202 					   "\x11\x0b\x98\x4c\x23";
203 	REQUIRE("e05fe287b73b0ce6639524cd86694311562914f4f6a3424101d885f88b05369c" == Hash().addData(s15, (ARRAY_LENGTH(s15) - 1)).finalize().toString());
204 
205 	const char s16[] = "\x02\x01\xf0\x46\x4b\x1e\x81\x68\x4e\x5e\xd6\xef\x28\x1b\x55\x62" \
206 					   "\x4e\xf4\x6c\xaa\x3b\x2d\x37\x48\x43\x72\xd9\x16\x10\xb6\x98\x25" \
207 					   "\x2c\xc9\xe0\x5f\xe2\x87\xb7\x3b\x0c\xe6\x63\x95\x24\xcd\x86\x69" \
208 					   "\x43\x11\x56\x29\x14\xf4\xf6\xa3\x42\x41\x01\xd8\x85\xf8\x8b\x05" \
209 					   "\x36\x9c";
210 	REQUIRE("4eb47d28ad3906d6244d01e0f6aec73b0b51de1574c13798184e4833dbae295a" == Hash().addData(s16, (ARRAY_LENGTH(s16) - 1)).finalize().toString());
211 
212 	const char s17[] = "\x03\x01\xf0\x46\x4b\x1e\x81\x68\x4e\x5e\xd6\xef\x28\x1b\x55\x62" \
213 					   "\x4e\xf4\x6c\xaa\x3b\x2d\x37\x48\x43\x72\xd9\x16\x10\xb6\x98\x25" \
214 					   "\x2c\xc9\xe0\x5f\xe2\x87\xb7\x3b\x0c\xe6\x63\x95\x24\xcd\x86\x69" \
215 					   "\x43\x11\x56\x29\x14\xf4\xf6\xa3\x42\x41\x01\xd8\x85\xf8\x8b\x05" \
216 					   "\x36\x9c";
217 	REQUIRE("588aa67064f24dc27ccaa1fab7e27dff811d500ad7ef2fb8f69ddf48cc0fecb7" == Hash().addData(s17, (ARRAY_LENGTH(s17) - 1)).finalize().toString());
218 
219 	const char s18[] = "\x57\xe7\xb6\x36\x23\xfa\xe5\xf0\x8c\xda\x46\x8e\x87\x2a\x20\xaf" \
220 					   "\xa0\x3d\xed\x41\xbf\x14\x03\x77\x65\x6e\x63\x72\x79\x70\x74\x69" \
221 					   "\x6f\x6e\x20\x73\x74\x61\x6e\x64\x61\x72\x64\x0e\x04\x0d\xc8\x3a" \
222 					   "\xf3\x1a\x67\x99\x1f\x2b\x01\xeb\xf9\xef\xd8\x88\x1f\x0a\x04\x93" \
223 					   "\x00\x06\x03";
224 	REQUIRE("6afb3bcebd76f82b252ce5eb25b5799686902b8cf2fd87536e55ef7603b09e7c" == Hash().addData(s18, (ARRAY_LENGTH(s18) - 1)).finalize().toString());
225 
226 	const char s19[] = "\x57\xe7\xb6\x36\x23\xfa\xe5\xf0\x8c\xda\x46\x8e\x87\x2a\x20\xaf" \
227 					   "\xa0\x3d\xed\x41\xbf\x14\x03\x77\x65\x6e\x63\x72\x79\x70\x74\x69" \
228 					   "\x6f\x6e\x20\x73\x74\x61\x6e\x64\x61\x72\x64\x0e\x04\x0d\xc8\x3a" \
229 					   "\xf3\x1a\x67\x99\x1f\x2b\x01\xeb\xf9\xef\xd8\x88\x1f\x0a\x04\x93" \
230 					   "\x00\x06\x03";
231 	REQUIRE("6afb3bcebd76f82b252ce5eb25b5799686902b8cf2fd87536e55ef7603b09e7c" == Hash().addData(s19, (ARRAY_LENGTH(s19) - 1)).finalize().toString());
232 
233 	const char s20[] = "\x64\xd2\x0d\x27\xd0\x63\x29\x57\xf8\x02\x8c\x1e\x02\x4f\x6b\x02" \
234 					   "\xed\xf2\x31\x02\xa5\x66\xc9\x32\xae\x8b\xd6\x13\xa8\xe8\x65\xfe" \
235 					   "\x65\x6e\x63\x72\x79\x70\x74\x69\x6f\x6e\x20\x73\x74\x61\x6e\x64" \
236 					   "\x61\x72\x64\x58\xd2\x25\xec\xa7\x84\xae\x30\x0a\x81\xa2\xd4\x82" \
237 					   "\x81\xa8\x28\xe1\xce\xdf\x11\xc4\x21\x90\x99\x84\x02\x65\x37\x50" \
238 					   "\x77\xbf\x78";
239 	REQUIRE("9c3d7360c30156fab7c80a0276712da9d8094a634b766d3a285e07480653426d" == Hash().addData(s20, (ARRAY_LENGTH(s20) - 1)).finalize().toString());
240 
241 	const char s21[] = "\x01\xc6\x27\x1b\x31\xf6\xbe\x39\x6a\x41\x66\xc0\x61\x6c\xf4\xa8" \
242 					   "\xac\xda\x5b\xef\x4d\xcb\xf2\xdd\x42\x65\x6e\x63\x72\x79\x70\x74" \
243 					   "\x69\x6f\x6e\x20\x73\x74\x61\x6e\x64\x61\x72\x64\x01\x47\xaf\x35" \
244 					   "\xdf\xa1\xbf\xe2\xf1\x61\x52\x1b\xcf\x59\xba\xb8\x35\x64\x86\x8d" \
245 					   "\x92\x95\x88\x17\x35";
246 	REQUIRE("f0a41f6f48ac723cecfc4b767299a5e25c0641679fbd2d4d20e9ffd5b9f0dab8" == Hash().addData(s21, (ARRAY_LENGTH(s21) - 1)).finalize().toString());
247 
248 	const char s22[] = "\x00\x83\xe6\x28\xcf\x70\x1e\xe3\x14\x1e\x88\x73\xfe\x55\x93\x6a" \
249 					   "\xdf\x24\x96\x3f\x5d\xc9\xc6\x48\x05\x66\xc8\x0f\x8a\x1d\x8c\xc5" \
250 					   "\x1b\x65\x6e\x63\x72\x79\x70\x74\x69\x6f\x6e\x20\x73\x74\x61\x6e" \
251 					   "\x64\x61\x72\x64\x01\x52\x4c\x64\x7f\x0c\x04\x12\xde\xfd\x46\x8b" \
252 					   "\xda\x3a\xe0\xe5\xa8\x0f\xcc\x8f\x5c\x99\x0f\xee\x11\x60\x29\x29" \
253 					   "\x23\x2d\xcd\x9f\x36";
254 	REQUIRE("73a48625d3758fa37b3eab80e9cfcaba665e3199ea15a1fa8189d96f579125e4" == Hash().addData(s22, (ARRAY_LENGTH(s22) - 1)).finalize().toString());
255 
256 
257 	// my own tests
258 	REQUIRE("1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b" == Hash().finalize().toString());
259 
260 	const char s30[] = "The quick brown fox jumps over the lazy dog";
261 	REQUIRE("5fdfe814b8573ca021983970fc79b2218c9570369b4859684e2e4c3fc76cb8ea" == Hash().addData(s30, strlen(s30)).finalize().toString());
262 
263 	const char s31[] = "The quick brown fox jumps over the lazy dog.";
264 	REQUIRE("2a41ce91b59a535379c0c0471a71abf8a268e62fa2f1281ebe93ed68a742dc3d" == Hash().addData(s31, strlen(s31)).finalize().toString());
265 
266 	const char s32[] = "The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dog";
267 	REQUIRE("806e7de3d0e9196246d0966b91ca92916532ebdcf5cee8958dca4cf37600aebc" == Hash().addData(s32, strlen(s32)).finalize().toString());
268 
269 	const std::vector<char> s33(65, 'a');
270 	REQUIRE("616ec433c359e7c2b19f360e2b8f2a1b6e9ed76b8dc1a7d207b31a5341c611e9"
271 			== Hash().addData(s33.data() + 1, s33.size() - 1).finalize().toString());
272 
273 	const int s34[2] = {0};
274 	const char s34_2[8] = {0};
275 	REQUIRE(Hash().addData(Hash::Span<const int>(s34)).finalize().toString()
276 			== Hash().addData(s34_2).finalize().toString());
277 
278 	const unsigned char s35[] = {0x00, 0x0A};
279 	const auto s35_1 = Hash().addData(s35, 2).finalize().toArray();
280 	const auto s35_2 = Hash().addData(s35).finalize().toArray();
281 	REQUIRE(s35_1 == s35_2);
282 }
283