OXYGENHUB
◆ main openmsx / src / unittest / sha1.cc
5.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "catch.hpp"
2
3
#include "sha1.hh"
4
5
#include "ranges.hh"
6
#include "xrange.hh"
7
8
#include <bit>
9
#include <cstring>
10
#include <sstream>
11
12
using namespace openmsx;
13
14
TEST_CASE("Sha1Sum: constructors")
15
{
16
	std::array<char, 40> buf;
17
	SECTION("default") {
18
		Sha1Sum sum;
19
		CHECK(sum.empty());
20
		CHECK(sum.toString(buf) == "0000000000000000000000000000000000000000");
21
	}
22
23
	SECTION("from string, ok") {
24
		Sha1Sum sum("1234567890123456789012345678901234567890");
25
		CHECK(!sum.empty());
26
		CHECK(sum.toString(buf) == "1234567890123456789012345678901234567890");
27
	}
28
	SECTION("from string, too short") {
29
		CHECK_THROWS(Sha1Sum("123456789012345678901234567890123456789"));
30
	}
31
	SECTION("from string, too long") {
32
		CHECK_THROWS(Sha1Sum("12345678901234567890123456789012345678901"));
33
	}
34
	SECTION("from string, invalid char") {
35
		CHECK_THROWS(Sha1Sum("g234567890123456789012345678901234567890"));
36
	}
37
}
38
39
TEST_CASE("Sha1Sum: parse")
40
{
41
	Sha1Sum sum;
42
	std::array<char, 40> buf;
43
44
	// precondition: string must be 40 chars long
45
	SECTION("ok") {
46
		sum.parse40(subspan<40>("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"));
47
		CHECK(sum.toString(buf) == "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd");
48
	}
49
	SECTION("invalid char") {
50
		CHECK_THROWS(sum.parse40(subspan<40>("abcdabcdabcdabcdabcdabcdabcdabcd-bcdabcd")));
51
	}
52
}
53
54
TEST_CASE("Sha1Sum: clear")
55
{
56
	Sha1Sum sum("1111111111111111111111111111111111111111");
57
	std::array<char, 40> buf;
58
	REQUIRE(!sum.empty());
59
	REQUIRE(sum.toString(buf) != "0000000000000000000000000000000000000000");
60
61
	sum.clear();
62
	CHECK(sum.empty());
63
	CHECK(sum.toString(buf) == "0000000000000000000000000000000000000000");
64
}
65
66
static void testCompare(const Sha1Sum& x, const Sha1Sum& y, bool expectEqual, bool expectLess)
67
{
68
	if (expectEqual) {
69
		REQUIRE(!expectLess);
70
		CHECK(  x == y );  CHECK(  y == x );
71
		CHECK(!(x != y));  CHECK(!(y != x));
72
73
		CHECK(!(x <  y));  CHECK(!(y <  x));
74
		CHECK(  x <= y );  CHECK(  y <= x );
75
		CHECK(!(x >  y));  CHECK(!(y >  x));
76
		CHECK(  x >= y );  CHECK(  y >= x );
77
	} else {
78
		CHECK(!(x == y));  CHECK(!(y == x));
79
		CHECK(  x != y );  CHECK(  y != x );
80
		if (expectLess) {
81
			CHECK(  x <  y );  CHECK(!(y <  x));
82
			CHECK(  x <= y );  CHECK(!(y <= x));
83
			CHECK(!(x >  y));  CHECK(  y >  x );
84
			CHECK(!(x >= y));  CHECK(  y >= x );
85
		} else {
86
			CHECK(!(x <  y));  CHECK(  y <  x );
87
			CHECK(!(x <= y));  CHECK(  y <= x );
88
			CHECK(  x >  y );  CHECK(!(y >  x));
89
			CHECK(  x >= y );  CHECK(!(y >= x));
90
		}
91
	}
92
}
93
94
TEST_CASE("Sha1Sum: comparisons")
95
{
96
	Sha1Sum sumA ("0000000000000000000000000000000000000000");
97
	Sha1Sum sumB ("0000000000000000000000000000000000000001");
98
	Sha1Sum sumB2("0000000000000000000000000000000000000001");
99
	Sha1Sum sumC ("0000000000100000000000000000000000000001");
100
101
	testCompare(sumB, sumB2, true, false);
102
	testCompare(sumA, sumB, false, true);
103
	testCompare(sumC, sumB, false, false);
104
}
105
106
TEST_CASE("Sha1Sum: stream")
107
{
108
	Sha1Sum sum("abcdef0123ABCDEF0123abcdef0123ABCDEF0123");
109
	std::stringstream ss;
110
	ss << sum;
111
	CHECK(ss.str() == "abcdef0123abcdef0123abcdef0123abcdef0123");
112
}
113
114
115
TEST_CASE("sha1: calc")
116
{
117
	const char* in = "abc";
118
	Sha1Sum output = SHA1::calc({std::bit_cast<const uint8_t*>(in), strlen(in)});
119
	std::array<char, 40> buf;
120
	CHECK(output.toString(buf) == "a9993e364706816aba3e25717850c26c9cd0d89d");
121
}
122
123
TEST_CASE("sha1: update,digest")
124
{
125
	SHA1 sha1;
126
	std::array<char, 40> buf;
127
	SECTION("single block") {
128
		const char* in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
129
		sha1.update({std::bit_cast<const uint8_t*>(in), strlen(in)});
130
		Sha1Sum sum1 = sha1.digest();
131
		Sha1Sum sum2 = sha1.digest(); // call 2nd time is ok
132
		CHECK(sum1 == sum2);
133
		CHECK(sum1.toString(buf) == "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
134
	}
135
	SECTION("multiple blocks") {
136
		const char* in = "aaaaaaaaaaaaaaaaaaaaaaaaa";
137
		REQUIRE(strlen(in) == 25);
138
		repeat(40000, [&] {
139
			sha1.update({std::bit_cast<const uint8_t*>(in), strlen(in)});
140
		});
141
		// 25 * 40'000 = 1'000'000 repetitions of "a"
142
		Sha1Sum sum = sha1.digest();
143
		CHECK(sum.toString(buf) == "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
144
	}
145
}
146
147
TEST_CASE("sha1: finalize")
148
{
149
	// white-box test for boundary cases in finalize()
150
	SHA1 sha1;
151
	std::array<char, 40> buf;
152
	const char* in = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
153
	                 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
154
	SECTION("0") {
155
		sha1.update({std::bit_cast<const uint8_t*>(in), 0uz});
156
		auto sum = sha1.digest();
157
		CHECK(sum.toString(buf) == "da39a3ee5e6b4b0d3255bfef95601890afd80709");
158
	}
159
	SECTION("25") {
160
		sha1.update({std::bit_cast<const uint8_t*>(in), 25uz});
161
		auto sum = sha1.digest();
162
		CHECK(sum.toString(buf) == "44f4647e1542a79d7d68ceb7f75d1dbf77fdebfc");
163
	}
164
	SECTION("55") {
165
		sha1.update({std::bit_cast<const uint8_t*>(in), 55uz});
166
		auto sum = sha1.digest();
167
		CHECK(sum.toString(buf) == "c1c8bbdc22796e28c0e15163d20899b65621d65a");
168
	}
169
	SECTION("56") {
170
		sha1.update({std::bit_cast<const uint8_t*>(in), 56uz});
171
		auto sum = sha1.digest();
172
		CHECK(sum.toString(buf) == "c2db330f6083854c99d4b5bfb6e8f29f201be699");
173
	}
174
	SECTION("60") {
175
		sha1.update({std::bit_cast<const uint8_t*>(in), 60uz});
176
		auto sum = sha1.digest();
177
		CHECK(sum.toString(buf) == "13d956033d9af449bfe2c4ef78c17c20469c4bf1");
178
	}
179
	SECTION("63") {
180
		sha1.update({std::bit_cast<const uint8_t*>(in), 63uz});
181
		auto sum = sha1.digest();
182
		CHECK(sum.toString(buf) == "03f09f5b158a7a8cdad920bddc29b81c18a551f5");
183
	}
184
	SECTION("64") {
185
		sha1.update({std::bit_cast<const uint8_t*>(in), 64uz});
186
		auto sum = sha1.digest();
187
		CHECK(sum.toString(buf) == "0098ba824b5c16427bd7a1122a5a442a25ec644d");
188
	}
189
}