diff options
author | Mattias Andrée <maandree@kth.se> | 2024-09-01 13:15:50 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-09-01 13:15:50 +0200 |
commit | b9d4bfaea3209fdcebdba148cb99242c44371c4a (patch) | |
tree | 94c15e93ed1bf712064f225da3db7e33e550869c | |
parent | Add tests for SHAKE and RawSHAKE (diff) | |
download | libhashsum-b9d4bfaea3209fdcebdba148cb99242c44371c4a.tar.gz libhashsum-b9d4bfaea3209fdcebdba148cb99242c44371c4a.tar.bz2 libhashsum-b9d4bfaea3209fdcebdba148cb99242c44371c4a.tar.xz |
Add tests for Keccak and fix squeeze support in finalise_const for Keccak
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | keccak.c | 244 | ||||
-rw-r--r-- | libhashsum_init_keccak__.c | 14 |
3 files changed, 258 insertions, 1 deletions
@@ -102,6 +102,7 @@ TEST =\ keccak_256.t\ keccak_384.t\ keccak_512.t\ + keccak.t\ sha3_224.t\ sha3_256.t\ sha3_384.t\ diff --git a/keccak.c b/keccak.c new file mode 100644 index 0000000..9b20bbc --- /dev/null +++ b/keccak.c @@ -0,0 +1,244 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef SUPPORT_KECCAK +# include "common.h" + +int +main(void) +{ + struct libhashsum_hasher hasher; + if (!libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 0)) { + fprintf(stderr, "expected libhashsum_init_keccak_hasher to fail, but it returned successfully\n"); + return 2; + } + if (errno != ENOSYS) { + perror("expected libhashsum_init_keccak_hasher to set errno to ENOSYS, but got"); + return 2; + } + return 0; +} + +#else +# include "common.h" + + +# define ASSERT(ASSERTION)\ + do {\ + if ((ASSERTION))\ + break;\ + fprintf(stderr, "assertion `%s` at line %i failed\n", #ASSERTION, __LINE__);\ + exit(2);\ + } while (0) + + +static const char * +hex(const struct libhashsum_hasher *hasher) +{ + static char buffer[4096]; + char *restrict out = buffer; + unsigned char *restrict in = hasher->hash_output; + size_t n = hasher->hash_size; + for (; n--; in++) { + *out++ = "0123456789abcdef"[(*in >> 4) & 15]; + *out++ = "0123456789abcdef"[(*in >> 0) & 15]; + } + *out = '\0'; + return buffer; +} + + +int +main(void) +{ + char buffer[4096]; + struct libhashsum_hasher h1, h2; + int i; + + for (i = 0; i < 8; i++) { + if ((i&3) == 3) + continue; + + ASSERT(!libhashsum_init_keccak_hasher(&h1, (i&1)?0: 1600 - 2 * 224, (i&2)?0: 2 * 224, 224, 1)); + ASSERT(!libhashsum_init_keccak_224_hasher(&h2)); + ASSERT(!h1.finalise_const(&h1, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(!h2.finalise_const(&h2, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(h1.hash_size == h2.hash_size); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h2.hash_size)); + ASSERT(h1.algorithm == h2.algorithm); + ASSERT(!strcmp(h1.algorithm_string, h2.algorithm_string)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, (i&1)?0: 1600 - 2 * 256, (i&2)?0: 2 * 256, 256, 1)); + ASSERT(!libhashsum_init_keccak_256_hasher(&h2)); + ASSERT(!h1.finalise_const(&h1, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(!h2.finalise_const(&h2, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(h1.hash_size == h2.hash_size); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h2.hash_size)); + ASSERT(h1.algorithm == h2.algorithm); + ASSERT(!strcmp(h1.algorithm_string, h2.algorithm_string)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, (i&1)?0: 1600 - 2 * 384, (i&2)?0: 2 * 384, 384, 1)); + ASSERT(!libhashsum_init_keccak_384_hasher(&h2)); + ASSERT(!h1.finalise_const(&h1, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(!h2.finalise_const(&h2, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(h1.hash_size == h2.hash_size); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h2.hash_size)); + ASSERT(h1.algorithm == h2.algorithm); + ASSERT(!strcmp(h1.algorithm_string, h2.algorithm_string)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, (i&1)?0: 1600 - 2 * 512, (i&2)?0: 2 * 512, 512, 1)); + ASSERT(!libhashsum_init_keccak_512_hasher(&h2)); + ASSERT(!h1.finalise_const(&h1, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(!h2.finalise_const(&h2, (i&4) ? "testdata" : 0, (i&4) ? 8 : 0, 0)); + ASSERT(h1.hash_size == h2.hash_size); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h2.hash_size)); + ASSERT(h1.algorithm == h2.algorithm); + ASSERT(!strcmp(h1.algorithm_string, h2.algorithm_string)); + } + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 224, 1)); + ASSERT(!libhashsum_init_keccak_224_hasher(&h2)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(!h2.finalise_const(&h2, NULL, 0, 0)); + ASSERT(h1.hash_size == h2.hash_size); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h2.hash_size)); + ASSERT(h1.algorithm == LIBHASHSUM_KECCAK); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=224]")); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 256, 1)); + ASSERT(!libhashsum_init_keccak_256_hasher(&h2)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(!h2.finalise_const(&h2, NULL, 0, 0)); + ASSERT(h1.hash_size == h2.hash_size); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h2.hash_size)); + ASSERT(h1.algorithm == LIBHASHSUM_KECCAK); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=256]")); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 512, 0)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(h1.hash_size == 512U / 8U); + ASSERT(h1.algorithm == LIBHASHSUM_KECCAK); + ASSERT(strcmp(h1.algorithm_string, h2.algorithm_string)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(h1.hash_size == 512U / 8U); + ASSERT(h1.algorithm == LIBHASHSUM_KECCAK); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 224, 1)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 512, 1)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, sizeof(buffer))); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, sizeof(buffer))); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + +#define Z1\ + "6753e3380c09e385d0339eb6b050a68f66cfd60a73476e6fd6adeb72f5edd7c6"\ + "f04a5d017a19cbe291935855b4860f69df04c98aa78b407a9ba9826f7266ef14" +#define Z2\ + "c3a2fa33f0bfb1cfef8da7875c4967f332c7fc93c050e81fb404f9a91503d601"\ + "0ee16f50b4ed0bc563ba8431668b003d7e2e6f226cb7fa93bb2e132c861fdc21" +#define Z200\ + "f8354bead24cc78c835813c0eec02dcad2b8caf37d79566ea6dc2836f231070d"\ + "cd786213580093a296578518ecc705c461264359e46c51b7c6beef3e3fb21a05" + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 1)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, sizeof(buffer))); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, sizeof(buffer))); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z1)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 200)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, sizeof(buffer))); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, sizeof(buffer))); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512,z=200]")); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z200)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 2)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, sizeof(buffer))); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, sizeof(buffer))); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512,z=2]")); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z2)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 224, 1)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 512, 1)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, 0)); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, 0)); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 1)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, 0)); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, 0)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z1)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 200)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, 0)); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, 0)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512,z=200]")); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z200)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 2)); + ASSERT(!h1.finalise(&h1, buffer, 0, 0, 0)); + ASSERT(!h2.finalise(&h2, buffer, 0, 0, 0)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512,z=2]")); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z2)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 224, 1)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 512, 1)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(!h2.finalise_const(&h2, NULL, 0, 0)); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 1)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(!h2.finalise_const(&h2, NULL, 0, 0)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z1)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 200)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(!h2.finalise_const(&h2, NULL, 0, 0)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512,z=200]")); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z200)); + + ASSERT(!libhashsum_init_keccak_hasher(&h1, 0, 0, 0, 0)); + ASSERT(!libhashsum_init_keccak_hasher(&h2, 0, 0, 0, 2)); + ASSERT(!h1.finalise_const(&h1, NULL, 0, 0)); + ASSERT(!h2.finalise_const(&h2, NULL, 0, 0)); + ASSERT(!strcmp(h1.algorithm_string, "Keccak[r=1024,c=576,n=512]")); + ASSERT(!strcmp(h2.algorithm_string, "Keccak[r=1024,c=576,n=512,z=2]")); + ASSERT(memcmp(h1.hash_output, h2.hash_output, h1.hash_size)); + ASSERT(!strcmp(hex(&h2), Z2)); + +#undef Z1 +#undef Z2 +#undef Z200 + + return 0; +} + + +#endif diff --git a/libhashsum_init_keccak__.c b/libhashsum_init_keccak__.c index ee146bc..9a9fa06 100644 --- a/libhashsum_init_keccak__.c +++ b/libhashsum_init_keccak__.c @@ -55,7 +55,19 @@ finalise_const(struct libhashsum_hasher *this, const void *data, size_t bytes, u else this->hash_output = this->state.keccak.sum.buf; } - libkeccak_digest(&this->state.keccak.s, m, bytes, extra_bits, this->state.keccak.suffix, this->hash_output); + libkeccak_digest(&this->state.keccak.s, m, bytes, extra_bits, this->state.keccak.suffix, + this->state.keccak.squeezes > 1U ? NULL : this->hash_output); + if (this->state.keccak.squeezes > 2U) { + size_t squeezes = this->state.keccak.squeezes - 2U; + while (squeezes > (size_t)LONG_MAX) { + libkeccak_fast_squeeze(&this->state.keccak.s, LONG_MAX); + squeezes -= (size_t)LONG_MAX; + } + libkeccak_fast_squeeze(&this->state.keccak.s, (long int)squeezes); + } + if (this->state.keccak.squeezes > 1U) + libkeccak_squeeze(&this->state.keccak.s, this->hash_output); + libkeccak_state_wipe_message(&this->state.keccak.s); this->stretch = &stretch; return 0; |