diff options
Diffstat (limited to '')
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | libhashsum.h | 72 | ||||
-rw-r--r-- | libhashsum_init_hasher_from_string.c | 26 | ||||
-rw-r--r-- | libhashsum_init_keccak_hasher2.c | 47 |
4 files changed, 136 insertions, 10 deletions
@@ -50,6 +50,7 @@ OBJ_PUBLIC =\ libhashsum_init_keccak_384_hasher.o\ libhashsum_init_keccak_512_hasher.o\ libhashsum_init_keccak_hasher.o\ + libhashsum_init_keccak_hasher2.o\ libhashsum_init_sha3_224_hasher.o\ libhashsum_init_sha3_256_hasher.o\ libhashsum_init_sha3_384_hasher.o\ diff --git a/libhashsum.h b/libhashsum.h index 79c2cb6..b57493e 100644 --- a/libhashsum.h +++ b/libhashsum.h @@ -617,6 +617,61 @@ struct libhashsum_hasher { }; +/** + * Keccak hash function parameters + * for `libhashsum_init_keccak_hasher2` + * + * @since 1.1 + */ +struct libhashsum_keccak_params { + /** + * The bitrate, 0 for automatic + * + * This must be a multiple of 8 + */ + size_t ratebits; + + /** + * The sponge capacity in bits, 0 for automatic + * + * This must be a multiple of 8 + */ + size_t capbits; + + /** + * The hash size in bits, 0 for automatic + */ + size_t hashbits; + + /** + * The state size in bits, 0 for automatic + * + * This must be 0 or `25 * .wordbits`, it must + * also be 0 or `.ratebits + .capbits`, however + * if `.ratebits` or `.capbits` is 0, this value + * must be less than non-zero value (if both + * are 0, only the "0 or `25 * .wordbits`" + * restriction apply) + */ + size_t statebits; + + /** + * The word size in bits, 0 for automatic + * + * This must be a multiple of 8 and a power of 2, + * currently supported value are (apart from 0): + '* 8, 16, 32, and 64 + */ + size_t wordbits; + + /** + * The number of squeezes to performed, + * 0 for automatic (which is 1) + */ + size_t squeezes; +}; + + #if defined(__GNUC__) # pragma GCC diagnostic pop #endif @@ -1018,6 +1073,23 @@ int libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebit size_t capbits, size_t hashbits, size_t squeezes); /** + * Create an initialised state for Keccak + * hashing and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @param param Hash function parameters + * @return 0 on success, -1 on failure + * + * @throws EINVAL `*params` is invalid + * @throws ENOSYS Support was excluded at compile time + * @throws ENOMEM Not enough memory available + * + * @since 1.1 + */ +LIBHASHSUM_NONNULL_ +int libhashsum_init_keccak_hasher2(struct libhashsum_hasher *this, const struct libhashsum_keccak_params *params); /* TODO man, test */ + +/** * Create an initialised state for SHA3-224 * hashing and return hash functions and details * diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c index e7a26d0..8ff5e44 100644 --- a/libhashsum_init_hasher_from_string.c +++ b/libhashsum_init_hasher_from_string.c @@ -51,31 +51,37 @@ einval: static int -with_rcnz(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t, size_t), +keccak(int (*initfunc)(struct libhashsum_hasher *, const struct libhashsum_keccak_params *params), struct libhashsum_hasher *this, const char *algorithm) { + struct libhashsum_keccak_params params = {0}; const char *p; - size_t r = 0, c = 0, n = 0, z = 0; p = strchr(algorithm, '['); if (!p || *++p == ']') { if (p && *++p) goto einval; - return initfunc(this, 0, 0, 0, 0); + return initfunc(this, ¶ms); } for (;;) { if (*p == 'r' || *p == 'R') { - if (parse_value(&r, &p[1], &p)) + if (parse_value(¶ms.ratebits, &p[1], &p)) goto einval; } else if (*p == 'c' || *p == 'C') { - if (parse_value(&c, &p[1], &p)) + if (parse_value(¶ms.capbits, &p[1], &p)) goto einval; - } else if (*p == 'n' || *p == 'N') { - if (parse_value(&n, &p[1], &p)) + } else if (*p == 'n' || *p == 'N' || *p == 'o' || *p == 'O') { + if (parse_value(¶ms.hashbits, &p[1], &p)) + goto einval; + } else if (*p == 's' || *p == 'S' || *p == 'b' || *p == 'B') { + if (parse_value(¶ms.statebits, &p[1], &p)) + goto einval; + } else if (*p == 'w' || *p == 'W') { + if (parse_value(¶ms.wordbits, &p[1], &p)) goto einval; } else if (*p == 'z' || *p == 'Z') { - if (parse_value(&z, &p[1], &p)) + if (parse_value(¶ms.squeezes, &p[1], &p)) goto einval; } else if (*p == ']') { break; @@ -90,7 +96,7 @@ with_rcnz(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t, si if (p[1]) goto einval; - return initfunc(this, r, c, n, z); + return initfunc(this, ¶ms); einval: errno = EINVAL; @@ -309,7 +315,7 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a case LIBHASHSUM_RAWSHAKE128: return with_n(&libhashsum_init_rawshake128_hasher, this, algorithm); case LIBHASHSUM_RAWSHAKE256: return with_n(&libhashsum_init_rawshake256_hasher, this, algorithm); case LIBHASHSUM_RAWSHAKE512: return with_n(&libhashsum_init_rawshake512_hasher, this, algorithm); - case LIBHASHSUM_KECCAK: return with_rcnz(&libhashsum_init_keccak_hasher, this, algorithm); + case LIBHASHSUM_KECCAK: return keccak(&libhashsum_init_keccak_hasher2, this, algorithm); case LIBHASHSUM_BLAKE224: return with_salt(&libhashsum_init_blake224_hasher, this, algorithm, 16U); case LIBHASHSUM_BLAKE256: return with_salt(&libhashsum_init_blake256_hasher, this, algorithm, 16U); case LIBHASHSUM_BLAKE384: return with_salt(&libhashsum_init_blake384_hasher, this, algorithm, 32U); diff --git a/libhashsum_init_keccak_hasher2.c b/libhashsum_init_keccak_hasher2.c new file mode 100644 index 0000000..71631f6 --- /dev/null +++ b/libhashsum_init_keccak_hasher2.c @@ -0,0 +1,47 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifdef SUPPORT_KECCAK + + +int +libhashsum_init_keccak_hasher2(struct libhashsum_hasher *this, const struct libhashsum_keccak_params *params) +{ + struct libkeccak_generalised_spec gspec; + struct libkeccak_spec spec; + + libkeccak_generalised_spec_initialise(&gspec); + if ((params->ratebits | params->capbits | + params->hashbits | params->statebits | + params->wordbits) > (size_t)LONG_MAX) + goto einval; + if (params->ratebits) + gspec.bitrate = (long int)params->ratebits; + if (params->capbits) + gspec.capacity = (long int)params->capbits; + if (params->hashbits) + gspec.output = (long int)params->hashbits; + if (params->statebits) + gspec.state_size = (long int)params->statebits; + if (params->wordbits) + gspec.word_size = (long int)params->wordbits; + if (libkeccak_degeneralise_spec(&gspec, &spec) || libkeccak_spec_check(&spec)) { + einval: + errno = EINVAL; + return -1; + } + + return libhashsum_init_keccak_hasher(this, (size_t)spec.bitrate, (size_t)spec.capacity, + (size_t)gspec.output, params->squeezes); +} + + +#else +int +libhashsum_init_keccak_hasher2(struct libhashsum_hasher *this, const struct libhashsum_keccak_params *params) +{ + (void) this; + (void) params; + errno = ENOSYS; + return -1; +} +#endif |