digestpp 1.0
C++11 header-only message digest library
Loading...
Searching...
No Matches
test_vectors.hpp
Go to the documentation of this file.
1
2#include <regex>
3#include <iostream>
4#include <fstream>
6
7template<typename T>
9{
10 template<typename U>
11 static auto test(int) -> decltype(std::declval<U>().set_customization(std::declval<std::string>()), std::true_type());
12 template<typename>
13 static std::false_type test(...);
14public:
15 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value;
16};
17
18template<typename T>
20{
21 template<typename U>
22 static auto test(int) -> decltype(std::declval<U>().set_personalization(std::declval<std::string>()), std::true_type());
23 template<typename>
24 static std::false_type test(...);
25public:
26 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value;
27};
28
29template<typename T>
31{
32 template<typename U>
33 static auto test(int) -> decltype(std::declval<U>().set_salt(std::declval<std::string>()), std::true_type());
34 template<typename>
35 static std::false_type test(...);
36public:
37 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value;
38};
39
40template<typename T>
42{
43 template<typename U>
44 static auto test(int) -> decltype(std::declval<U>().set_key(std::declval<std::string>()), std::true_type());
45 template<typename>
46 static std::false_type test(...);
47public:
48 static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value;
49};
50
51inline std::string hex2string(const std::string& hex)
52{
53 std::string res;
54 res.resize(hex.length() / 2);
55 for (size_t i = 0; i < hex.length(); i += 2)
56 res[i / 2] = static_cast<char>(strtoul(hex.substr(i, 2).c_str(), nullptr, 16));
57 return res;
58}
59
60inline void trim_string(std::string& str)
61{
62 str.erase(str.find_last_not_of("\r\n\t ") + 1);
63 str.erase(0, str.find_first_not_of("\r\n\t "));
64}
65
66inline std::pair<std::string, std::string> split_vector(const std::string& str)
67{
68 std::pair<std::string, std::string> res;
69 auto sep = str.find("=");
70 if (sep == str.npos)
71 return res;
72
73 res.first = str.substr(0, sep);
74 res.second = str.substr(sep + 1);
75 trim_string(res.first);
76 trim_string(res.second);
77 return res;
78}
79
80template<typename H, template<typename> class M, typename std::enable_if<!digestpp::detail::is_xof<H>::value>::type* = nullptr>
81std::string compute_vector(const std::string&, digestpp::hasher<H, M>& hasher)
82{
83 return hasher.hexdigest();
84}
85
86template<typename H, template<typename> class M, typename std::enable_if<digestpp::detail::is_xof<H>::value>::type* = nullptr>
87std::string compute_vector(const std::string& expected, digestpp::hasher<H, M>& hasher)
88{
89 return hasher.hexsqueeze(expected.size() / 2);
90}
91
92template<typename H, typename std::enable_if<!has_customization<H>::value && !has_personalization<H>::value>::type* = nullptr>
93void set_customization(const std::string& customization, H& hasher)
94{
95}
96
97template<typename H, typename std::enable_if<has_customization<H>::value>::type* = nullptr>
98void set_customization(const std::string& customization, H& hasher)
99{
100 hasher.set_customization(customization);
101}
102
103template<typename H, typename std::enable_if<has_personalization<H>::value>::type* = nullptr>
104void set_customization(const std::string& customization, H& hasher)
105{
106 hasher.set_personalization(customization);
107}
108
109template<typename H, typename std::enable_if<!has_salt<H>::value>::type* = nullptr>
110void set_salt(const std::string& salt, H& hasher)
111{
112}
113
114template<typename H, typename std::enable_if<has_salt<H>::value>::type* = nullptr>
115void set_salt(const std::string& salt, H& hasher)
116{
117 hasher.set_salt(salt);
118}
119
120template<typename H, typename std::enable_if<!has_key<H>::value>::type* = nullptr>
121void set_key(const std::string& key, H& hasher)
122{
123}
124
125template<typename H, typename std::enable_if<has_key<H>::value>::type* = nullptr>
126void set_key(const std::string& key, H& hasher)
127{
128 hasher.set_key(key);
129}
130
131template<typename H>
132void test_vectors(const H& hasher, const char* name, const char* filename)
133{
134 H copy(hasher);
135 std::ifstream file(filename, std::ios::in);
136 std::string line;
137 unsigned int count = 0, failed = 0, success = 0;
138 std::string::size_type msgbytes = 0;
139 while (std::getline(file, line))
140 {
141 auto splitted = split_vector(line);
142 std::string second = splitted.second;
143 if (splitted.first == "Bytes")
144 msgbytes = std::stol(splitted.second);
145 if (splitted.first == "C")
146 {
147 std::string teststr = hex2string(second);
148 set_customization(teststr, copy);
149 }
150 if (splitted.first == "Salt")
151 {
152 std::string teststr = hex2string(second);
153 set_salt(teststr, copy);
154 }
155 if (splitted.first == "Key")
156 {
157 std::string teststr = hex2string(second);
158 set_key(teststr, copy);
159 }
160 if (splitted.first == "Msg")
161 {
162 std::string teststr = hex2string(second);
163 if (!msgbytes)
164 copy.absorb(teststr);
165 else while (msgbytes)
166 {
167 auto toabsorb = std::min(teststr.size(), msgbytes);
168 copy.absorb(teststr.c_str(), toabsorb);
169 msgbytes -= toabsorb;
170 }
171 }
172 if (splitted.first == "MD")
173 {
174 std::transform(second.begin(), second.end(), second.begin(), [](unsigned char c) { return tolower(c); });
175 std::string actual = compute_vector(second, copy);
176 if (second != actual)
177 {
178 std::cerr << "\nError for test " << count << "\nExpected: " << second
179 << "\nActual: " << actual << std::endl;
180 failed++;
181 }
182 else success++;
183 count++;
184 copy.reset();
185 }
186 }
187 std::cout << name << ": ";
188 if (success)
189 std::cout << success << "/" << count << " OK";
190 if (failed && success)
191 std::cout << ", ";
192 if (failed)
193 std::cout << failed << "/" << count << " FAILED";
194 if (!success && !failed)
195 std::cout << "No tests found. Make sure that file " << filename << " exists.";
196 std::cout << std::endl;
197}
198
Main class template implementing the public API for hashing.
Definition hasher.hpp:38
std::string hexdigest() const
Return hex digest of absorbed data.
Definition hasher.hpp:372
std::string hexsqueeze(size_t len)
Squeeze bytes and return them as a hex string.
Definition hasher.hpp:296
Definition test_vectors.hpp:9
static constexpr bool value
Definition test_vectors.hpp:15
Definition test_vectors.hpp:42
static constexpr bool value
Definition test_vectors.hpp:48
Definition test_vectors.hpp:20
static constexpr bool value
Definition test_vectors.hpp:26
Definition test_vectors.hpp:31
static constexpr bool value
Definition test_vectors.hpp:37
void set_salt(const std::string &salt, H &hasher)
Definition test_vectors.hpp:110
void set_customization(const std::string &customization, H &hasher)
Definition test_vectors.hpp:93
void set_key(const std::string &key, H &hasher)
Definition test_vectors.hpp:121
std::string hex2string(const std::string &hex)
Definition test_vectors.hpp:51
std::pair< std::string, std::string > split_vector(const std::string &str)
Definition test_vectors.hpp:66
void test_vectors(const H &hasher, const char *name, const char *filename)
Definition test_vectors.hpp:132
void trim_string(std::string &str)
Definition test_vectors.hpp:60
std::string compute_vector(const std::string &, digestpp::hasher< H, M > &hasher)
Definition test_vectors.hpp:81