aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile1
-rw-r--r--libhashsum.h72
-rw-r--r--libhashsum_init_hasher_from_string.c26
-rw-r--r--libhashsum_init_keccak_hasher2.c47
4 files changed, 136 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index e0415b1..b1da346 100644
--- a/Makefile
+++ b/Makefile
@@ -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, &params);
}
for (;;) {
if (*p == 'r' || *p == 'R') {
- if (parse_value(&r, &p[1], &p))
+ if (parse_value(&params.ratebits, &p[1], &p))
goto einval;
} else if (*p == 'c' || *p == 'C') {
- if (parse_value(&c, &p[1], &p))
+ if (parse_value(&params.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(&params.hashbits, &p[1], &p))
+ goto einval;
+ } else if (*p == 's' || *p == 'S' || *p == 'b' || *p == 'B') {
+ if (parse_value(&params.statebits, &p[1], &p))
+ goto einval;
+ } else if (*p == 'w' || *p == 'W') {
+ if (parse_value(&params.wordbits, &p[1], &p))
goto einval;
} else if (*p == 'z' || *p == 'Z') {
- if (parse_value(&z, &p[1], &p))
+ if (parse_value(&params.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, &params);
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