From 6f35ae7007f0f9b54e5798d6a63ffbd1f9f9d59c Mon Sep 17 00:00:00 2001 From: Alain Mosnier Date: Fri, 15 Dec 2017 21:34:20 +0100 Subject: [PATCH] Added extensive testing --- README.md | 55 ++++++++++++++++++---- test.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 180 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 447e37b..4a2c7db 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,6 @@ At the moment, only SHA-256 is implemented. [Wikipedia](https://en.wikipedia.org/wiki/SHA-2). At the moment, no effort at all has been put on optimization. -## Testing - -Some testing has been performed, that hopefully proves that the -implementation is correct. However, no effort has so far been put into -testing large sizes of data. - ## Notes The Makefile is as minimal as possible. No effort was put into making @@ -36,8 +30,53 @@ include in any project, may it use GNU make or any other build tool. ## Code review -This code has been posted for review at [Stack Exchange CODE -REVIEW](https://codereview.stackexchange.com/questions/182812/self-contained-sha-256-implementation-in-c). +This code has been reviewed at [Stack Exchange CODE +REVIEW](https://codereview.stackexchange.com/questions/182812/self-contained-sha-256-implementation-in-c), +and the implementation has been improved accordingly. + +## Testing + +The implementation has been successfully tested on an x86-64 machine +under Linux as well as on a 16-bit DSP. On the x86-64 machine, all the +available NIST test vectors where successfully tested ([SHA-256 +examples](https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA256.pdf) +and [SHA-2 Additional +examples](https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA2_Additional.pdf), +plus a few others): + +`Input Message: "abc" +Message Digest is BA7816BF 8F01CFEA 414140DE 5DAE2223 B00361A3 96177A9C B410FF61 F20015AD` + +`Input Message: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" +Message Digest is 248D6A61 D20638B8 E5C02693 0C3E6039 A33CE459 64FF2167 F6ECEDD4 19DB06C1` + +`SHA-256 Test Data +#1) 1 byte 0xbd +68325720 aabd7c82 f30f554b 313d0570 c95accbb 7dc4b5aa e11204c0 8ffe732b +#2) 4 bytes 0xc98c8e55 +7abc22c0 ae5af26c e93dbb94 433a0e0b 2e119d01 4f8e7f65 bd56c61c cccd9504 +#3) 55 bytes of zeros +02779466 cdec1638 11d07881 5c633f21 90141308 1449002f 24aa3e80 f0b88ef7 +#4) 56 bytes of zeros +d4817aa5 497628e7 c77e6b60 6107042b bba31308 88c5f47a 375e6179 be789fbb +#5) 57 bytes of zeros +65a16cb7 861335d5 ace3c607 18b5052e 44660726 da4cd13b b745381b 235a1785 +#6) 64 bytes of zeros +f5a5fd42 d16a2030 2798ef6e d309979b 43003d23 20d9f0e8 ea9831a9 2759fb4b +#7) 1000 bytes of zeros +541b3e9d aa09b20b f85fa273 e5cbd3e8 0185aa4e c298e765 db87742b 70138a53 +#8) 1000 bytes of 0x41 ‘A’ +c2e68682 3489ced2 017f6059 b8b23931 8b6364f6 dcd835d0 a519105a 1eadd6e4 +#9) 1005 bytes of 0x55 ‘U’ +f4d62dde c0f3dd90 ea1380fa 16a5ff8d c4c54b21 740650f2 4afc4120 903552b0 +#10) 1000000 bytes of zeros +d29751f2 649b32ff 572b5e0a 9f541ea6 60a50f94 ff0beedf b0b692b9 24cc8025 +#11) 0x20000000 (536870912) bytes of 0x5a ‘Z’ +15a1868c 12cc5395 1e182344 277447cd 0979536b adcc512a d24c67e9 b2d4f3dd +#12) 0x41000000 (1090519040) bytes of zeros +461c19a9 3bd4344f 9215f5ec 64357090 342bc66b 15a14831 7d276e31 cbc20b53 +#13) 0x6000003e (1610612798) bytes of 0x42 ‘B’ +c23ce8a7 895f4b21 ec0daf37 920ac0a2 62a22004 5a03eb2d fed48ef9 b05aabea` ## License diff --git a/test.c b/test.c index 9098af2..c64c7a4 100644 --- a/test.c +++ b/test.c @@ -4,12 +4,12 @@ #include "sha-256.h" -struct vector { +struct string_vector { const char *input; const char *output; }; -static const struct vector VECTORS[] = { +static const struct string_vector STRING_VECTORS[] = { { "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" @@ -65,6 +65,115 @@ static const struct vector VECTORS[] = { } }; +#define LARGE_MESSAGES 0 + +static uint8_t data1[] = { 0xbd }; +static uint8_t data2[] = { 0xc9, 0x8c, 0x8e, 0x55 }; +static uint8_t data7[1000]; +static uint8_t data8[1000]; +static uint8_t data9[1005]; +#if LARGE_MESSAGES +static uint8_t data11[536870912]; +static uint8_t data12[1090519040]; +static uint8_t data13[1610612798]; +#endif + +static void construct_binary_messages(void) +{ + size_t i; + for (i = 0; i < sizeof data7; i++) + data7[i] = 0; + for (i = 0; i < sizeof data8; i++) + data8[i] = 0x41; + for (i = 0; i < sizeof data9; i++) + data9[i] = 0x55; +#if LARGE_MESSAGES + for (i = 0; i < sizeof data11; i++) + data11[i] = 0x5a; + for (i = 0; i < sizeof data12; i++) + data12[i] = 0; + for (i = 0; i < sizeof data13; i++) + data13[i] = 0x42; +#endif +} + +struct vector { + const uint8_t *input; + size_t input_len; + const char *output; +}; + +static const struct vector VECTORS[] = { + { + data1, + sizeof data1, + "68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b" + }, + { + data2, + sizeof data2, + "7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504" + }, + { + data7, + 55, + "02779466cdec163811d078815c633f21901413081449002f24aa3e80f0b88ef7" + }, + { + data7, + 56, + "d4817aa5497628e7c77e6b606107042bbba3130888c5f47a375e6179be789fbb" + }, + { + data7, + 57, + "65a16cb7861335d5ace3c60718b5052e44660726da4cd13bb745381b235a1785" + }, + { + data7, + 64, + "f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b" + }, + { + data7, + sizeof data7, + "541b3e9daa09b20bf85fa273e5cbd3e80185aa4ec298e765db87742b70138a53" + }, + { + data8, + sizeof data8, + "c2e686823489ced2017f6059b8b239318b6364f6dcd835d0a519105a1eadd6e4" + }, + { + data9, + sizeof data9, + "f4d62ddec0f3dd90ea1380fa16a5ff8dc4c54b21740650f24afc4120903552b0" + } +#if LARGE_MESSAGES + , + { + data12, + 1000000, + "d29751f2649b32ff572b5e0a9f541ea660a50f94ff0beedfb0b692b924cc8025" + }, + { + data11, + sizeof data11, + "15a1868c12cc53951e182344277447cd0979536badcc512ad24c67e9b2d4f3dd" + }, + { + data12, + sizeof data12, + "461c19a93bd4344f9215f5ec64357090342bc66b15a148317d276e31cbc20b53" + }, + { + data13, + sizeof data13, + "c23ce8a7895f4b21ec0daf37920ac0a262a220045a03eb2dfed48ef9b05aabea" + } +#endif +}; + static void hash_to_string(char string[65], const uint8_t hash[32]) { size_t i; @@ -73,7 +182,7 @@ static void hash_to_string(char string[65], const uint8_t hash[32]) } } -static void test(const char input[], const char output[]) +static void string_test(const char input[], const char output[]) { uint8_t hash[32]; char hash_string[65]; @@ -87,14 +196,33 @@ static void test(const char input[], const char output[]) printf("SUCCESS!\n\n"); } } - + +static void test(const uint8_t * input, size_t input_len, const char output[]) +{ + uint8_t hash[32]; + char hash_string[65]; + calc_sha_256(hash, input, input_len); + hash_to_string(hash_string, hash); + printf("input starts with 0x%02x, length %lu\n", *input, input_len); + printf("hash : %s\n", hash_string); + if (strcmp(output, hash_string)) { + printf("FAILURE!\n\n"); + } else { + printf("SUCCESS!\n\n"); + } +} int main(void) { size_t i; + for (i = 0; i < (sizeof STRING_VECTORS / sizeof (struct string_vector)); i++) { + const struct string_vector *vector = &STRING_VECTORS[i]; + string_test(vector->input, vector->output); + } + construct_binary_messages(); for (i = 0; i < (sizeof VECTORS / sizeof (struct vector)); i++) { const struct vector *vector = &VECTORS[i]; - test(vector->input, vector->output); + test(vector->input, vector->input_len, vector->output); } return 0; }