2022-06-29 19:03:12 +02:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2022-06-29 21:29:15 +02:00
|
|
|
#include "../lib/helper.h"
|
|
|
|
#include "../lib/io.h"
|
|
|
|
#include "../lib/md2.h"
|
2022-06-29 10:50:55 +02:00
|
|
|
|
2022-06-29 19:03:12 +02:00
|
|
|
// Returns true when val is approx. equal to exp.
|
2022-07-07 17:45:33 +02:00
|
|
|
static bool runTest(struct configuration* c, const char* message,
|
|
|
|
const char* expectedHash) {
|
2022-06-29 19:03:12 +02:00
|
|
|
uint8_t out[16];
|
2022-07-07 17:45:33 +02:00
|
|
|
double duration = 0.0;
|
|
|
|
|
|
|
|
if (c->doBenchmark) {
|
|
|
|
duration = run_benchmark(c->benchmarkingCycles, md2_hash, strlen(message),
|
|
|
|
(uint8_t*)message, out);
|
|
|
|
} else {
|
|
|
|
md2_hash(strlen(message), (uint8_t*)message, out);
|
|
|
|
}
|
2022-06-29 19:03:12 +02:00
|
|
|
|
|
|
|
char hash[32];
|
2022-07-04 18:02:34 +02:00
|
|
|
md2_encode_hash(out, hash);
|
2022-06-29 19:03:12 +02:00
|
|
|
|
2022-07-06 20:35:10 +02:00
|
|
|
bool ok = !strncmp(hash, expectedHash, 32);
|
2022-07-07 17:45:33 +02:00
|
|
|
printf("%s: md2(%s) %s == %s", "not ok" + (4 * ok), message, hash,
|
|
|
|
expectedHash);
|
|
|
|
|
|
|
|
if (c->doBenchmark) {
|
2022-07-07 18:13:53 +02:00
|
|
|
printf(" took: %f", duration);
|
2022-07-07 17:45:33 +02:00
|
|
|
}
|
|
|
|
printf("\n");
|
2022-06-29 19:03:12 +02:00
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2022-07-07 17:45:33 +02:00
|
|
|
unsigned runTests(struct configuration* c) {
|
2022-06-29 19:03:12 +02:00
|
|
|
unsigned failed = 0;
|
2022-07-04 18:02:34 +02:00
|
|
|
// src: https://datatracker.ietf.org/doc/html/rfc1319#appendix-A.5
|
2022-07-07 17:45:33 +02:00
|
|
|
failed += !runTest(c, "", "8350e5a3e24c153df2275c9f80692773");
|
|
|
|
failed += !runTest(c, "a", "32ec01ec4a6dac72c0ab96fb34c0b5d1");
|
|
|
|
failed += !runTest(c, "abc", "da853b0d3f88d99b30283a69e6ded6bb");
|
|
|
|
failed += !runTest(c, "message digest", "ab4f496bfb2a530b219ff33031fe06b0");
|
|
|
|
failed += !runTest(c, "jebdjcslfhwfdig", "e1b69085c6f6e36cb8fe8d98ed3f2c35");
|
|
|
|
failed += !runTest(c, "0123456789abcde", "d95629645108a20ab4d70e8545e0723b");
|
|
|
|
failed += !runTest(c, "0123456789abcdef", "12c8dfa285f14e1af8c5254e7092d0d3");
|
2022-06-29 19:03:12 +02:00
|
|
|
failed +=
|
2022-07-07 17:45:33 +02:00
|
|
|
!runTest(c, "0123456789abcdefg", "e4d0efded5ef7b6843a5ba47e1171347");
|
|
|
|
failed += !runTest(c, "abcdefghijklmnopqrstuvwxyz",
|
|
|
|
"4e8ddff3650292ab5a4108c3aa47940b");
|
|
|
|
failed += !runTest(
|
|
|
|
c, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
|
|
"da33def2a42df13975352846c30338cd");
|
2022-06-29 19:03:12 +02:00
|
|
|
failed += !runTest(
|
2022-07-07 17:45:33 +02:00
|
|
|
c,
|
2022-06-29 19:03:12 +02:00
|
|
|
"123456789012345678901234567890123456789012345678901234567890123456789012"
|
|
|
|
"34567890",
|
|
|
|
"d5976f79d83d3a0dc9806c3c66f3efd8");
|
|
|
|
|
|
|
|
if (failed)
|
|
|
|
printf("%u tests FAILED\n", failed);
|
|
|
|
else
|
|
|
|
printf("All tests PASSED\n");
|
|
|
|
|
|
|
|
return failed;
|
|
|
|
}
|
|
|
|
|
2022-06-29 10:50:55 +02:00
|
|
|
int main(int argc, char** argv) {
|
2022-06-29 11:12:35 +02:00
|
|
|
struct configuration c;
|
|
|
|
enum argumentParseResult result = parseArguments(argc, argv, &c);
|
2022-06-29 10:50:55 +02:00
|
|
|
|
2022-06-29 11:12:35 +02:00
|
|
|
switch (result) {
|
2022-06-29 10:50:55 +02:00
|
|
|
case RESULT_EXIT_SUCCESS:
|
2022-06-29 11:12:35 +02:00
|
|
|
return EXIT_SUCCESS;
|
2022-06-29 10:50:55 +02:00
|
|
|
case RESULT_EXIT_FAILURE:
|
2022-06-29 11:12:35 +02:00
|
|
|
return EXIT_FAILURE;
|
2022-06-29 10:50:55 +02:00
|
|
|
default:
|
2022-06-29 11:12:35 +02:00
|
|
|
break;
|
|
|
|
}
|
2022-06-29 10:50:55 +02:00
|
|
|
|
2022-07-04 18:02:34 +02:00
|
|
|
if (!md2_choose_implementation(c.implementationToUse)) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"%s: invalid argument, implementation '%d' does not exist!\n",
|
|
|
|
argv[0], c.implementationToUse);
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2022-06-29 11:12:35 +02:00
|
|
|
printf(
|
2022-07-07 17:45:33 +02:00
|
|
|
"Using implementation: %d, doing benchmark: %d, "
|
2022-06-29 11:12:35 +02:00
|
|
|
"benchmark cycles: %d\n",
|
2022-07-07 17:45:33 +02:00
|
|
|
c.implementationToUse, c.doBenchmark, c.benchmarkingCycles);
|
|
|
|
|
|
|
|
if (c.runTests) {
|
|
|
|
printf("Running tests...\n\n");
|
|
|
|
return runTests(&c);
|
|
|
|
}
|
2022-06-29 10:50:55 +02:00
|
|
|
|
2022-07-07 17:45:33 +02:00
|
|
|
printf("Hashing file %s...\n\n", c.filename);
|
2022-06-29 20:54:41 +02:00
|
|
|
size_t len;
|
2022-06-29 22:02:18 +02:00
|
|
|
uint8_t* data = read_file(c.filename, &len);
|
|
|
|
if (data == NULL) {
|
2022-06-29 20:54:41 +02:00
|
|
|
printf("Error reading file %s!", c.filename);
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2022-06-29 22:02:18 +02:00
|
|
|
|
2022-06-29 15:41:56 +02:00
|
|
|
uint8_t out[16];
|
2022-06-29 21:45:45 +02:00
|
|
|
char hash[32];
|
2022-07-07 17:15:41 +02:00
|
|
|
if (c.doBenchmark) {
|
|
|
|
double duration =
|
|
|
|
run_benchmark(c.benchmarkingCycles, md2_hash, len, data, out);
|
|
|
|
printf("Running %d cycles took %f seconds\n", c.benchmarkingCycles,
|
|
|
|
duration);
|
|
|
|
} else {
|
|
|
|
md2_hash(len, data, out);
|
|
|
|
}
|
2022-07-04 18:02:34 +02:00
|
|
|
md2_encode_hash(out, hash);
|
2022-07-07 17:15:41 +02:00
|
|
|
printf("Hash: %s\n", hash);
|
2022-06-29 15:41:56 +02:00
|
|
|
|
2022-06-29 21:45:45 +02:00
|
|
|
free(data);
|
|
|
|
|
2022-06-29 11:12:35 +02:00
|
|
|
return 0;
|
2022-06-29 10:50:55 +02:00
|
|
|
}
|