openMSX
unittest/sha1.cc
Go to the documentation of this file.
1 #include "catch.hpp"
2 #include "sha1.hh"
3 #include <sstream>
4 
5 using namespace openmsx;
6 
7 TEST_CASE("Sha1Sum: constructors")
8 {
9  SECTION("default") {
10  Sha1Sum sum;
11  CHECK(sum.empty());
12  CHECK(sum.toString() == "0000000000000000000000000000000000000000");
13  }
14 
15  SECTION("from string, ok") {
16  Sha1Sum sum("1234567890123456789012345678901234567890");
17  CHECK(!sum.empty());
18  CHECK(sum.toString() == "1234567890123456789012345678901234567890");
19  }
20  SECTION("from string, too short") {
21  CHECK_THROWS(Sha1Sum("123456789012345678901234567890123456789"));
22  }
23  SECTION("from string, too long") {
24  CHECK_THROWS(Sha1Sum("12345678901234567890123456789012345678901"));
25  }
26  SECTION("from string, invalid char") {
27  CHECK_THROWS(Sha1Sum("g234567890123456789012345678901234567890"));
28  }
29 }
30 
31 TEST_CASE("Sha1Sum: parse")
32 {
33  Sha1Sum sum;
34 
35  // precondition: string must be 40 chars long
36  SECTION("ok") {
37  sum.parse40("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd");
38  CHECK(sum.toString() == "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd");
39  }
40  SECTION("invalid char") {
41  CHECK_THROWS(sum.parse40("abcdabcdabcdabcdabcdabcdabcdabcd-bcdabcd"));
42  }
43 }
44 
45 TEST_CASE("Sha1Sum: clear")
46 {
47  Sha1Sum sum("1111111111111111111111111111111111111111");
48  REQUIRE(!sum.empty());
49  REQUIRE(sum.toString() != "0000000000000000000000000000000000000000");
50 
51  sum.clear();
52  CHECK(sum.empty());
53  CHECK(sum.toString() == "0000000000000000000000000000000000000000");
54 }
55 
56 static void testCompare(const Sha1Sum& x, const Sha1Sum& y, bool expectEqual, bool expectLess)
57 {
58  if (expectEqual) {
59  REQUIRE(!expectLess);
60  CHECK( x == y ); CHECK( y == x );
61  CHECK(!(x != y)); CHECK(!(y != x));
62 
63  CHECK(!(x < y)); CHECK(!(y < x));
64  CHECK( x <= y ); CHECK( y <= x );
65  CHECK(!(x > y)); CHECK(!(y > x));
66  CHECK( x >= y ); CHECK( y >= x );
67  } else {
68  CHECK(!(x == y)); CHECK(!(y == x));
69  CHECK( x != y ); CHECK( y != x );
70  if (expectLess) {
71  CHECK( x < y ); CHECK(!(y < x));
72  CHECK( x <= y ); CHECK(!(y <= x));
73  CHECK(!(x > y)); CHECK( y > x );
74  CHECK(!(x >= y)); CHECK( y >= x );
75  } else {
76  CHECK(!(x < y)); CHECK( y < x );
77  CHECK(!(x <= y)); CHECK( y <= x );
78  CHECK( x > y ); CHECK(!(y > x));
79  CHECK( x >= y ); CHECK(!(y >= x));
80  }
81  }
82 }
83 
84 TEST_CASE("Sha1Sum: comparisons")
85 {
86  Sha1Sum sumA ("0000000000000000000000000000000000000000");
87  Sha1Sum sumB ("0000000000000000000000000000000000000001");
88  Sha1Sum sumB2("0000000000000000000000000000000000000001");
89  Sha1Sum sumC ("0000000000100000000000000000000000000001");
90 
91  testCompare(sumB, sumB2, true, false);
92  testCompare(sumA, sumB, false, true);
93  testCompare(sumC, sumB, false, false);
94 }
95 
96 TEST_CASE("Sha1Sum: stream")
97 {
98  Sha1Sum sum("abcdef0123ABCDEF0123abcdef0123ABCDEF0123");
99  std::stringstream ss;
100  ss << sum;
101  CHECK(ss.str() == "abcdef0123abcdef0123abcdef0123abcdef0123");
102 }
103 
104 
105 TEST_CASE("sha1: calc")
106 {
107  const char* in = "abc";
108  Sha1Sum output = SHA1::calc(reinterpret_cast<const uint8_t*>(in), strlen(in));
109  CHECK(output.toString() == "a9993e364706816aba3e25717850c26c9cd0d89d");
110 }
111 
112 TEST_CASE("sha1: update,digest")
113 {
114  SHA1 sha1;
115  SECTION("single block") {
116  const char* in = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
117  sha1.update(reinterpret_cast<const uint8_t*>(in), strlen(in));
118  Sha1Sum sum1 = sha1.digest();
119  Sha1Sum sum2 = sha1.digest(); // call 2nd time is ok
120  CHECK(sum1 == sum2);
121  CHECK(sum1.toString() == "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
122  }
123  SECTION("multiple blocks") {
124  const char* in = "aaaaaaaaaaaaaaaaaaaaaaaaa";
125  REQUIRE(strlen(in) == 25);
126  for (int i = 0; i < 40000; ++i) {
127  sha1.update(reinterpret_cast<const uint8_t*>(in), strlen(in));
128  }
129  // 25 * 40'000 = 1'000'000 repetitions of "a"
130  Sha1Sum sum = sha1.digest();
131  CHECK(sum.toString() == "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
132  }
133 }
void update(const uint8_t *data, size_t len)
Incrementally calculate the hash value.
Definition: utils/sha1.cc:318
auto sum(InputRange &&range)
Definition: stl.hh:302
static Sha1Sum calc(const uint8_t *data, size_t len)
Easier to use interface, if you can pass all data in one go.
Definition: utils/sha1.cc:361
bool empty() const
Definition: utils/sha1.cc:244
This class represents the result of a sha1 calculation (a 160-bit value).
Definition: sha1.hh:19
Sha1Sum digest()
Get the final hash.
Definition: utils/sha1.cc:355
CHECK(m3==m3)
constexpr size_t strlen(const char *s) noexcept
Definition: cstd.hh:135
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
Helper class to perform a sha1 calculation.
Definition: sha1.hh:78
std::string toString() const
Definition: utils/sha1.cc:232
void parse40(const char *str)
Parse from a 40-character long buffer.
Definition: utils/sha1.cc:141
TEST_CASE("Sha1Sum: constructors")
Definition: unittest/sha1.cc:7