aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libkeccak/spec.h12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/libkeccak/spec.h b/src/libkeccak/spec.h
index cccd27c..3e14f8e 100644
--- a/src/libkeccak/spec.h
+++ b/src/libkeccak/spec.h
@@ -20,6 +20,7 @@
#define LIBKECCAK_SPEC_H 1
+#include <stdint.h>
#include <limits.h>
@@ -167,7 +168,7 @@ static inline __attribute__((nonnull, nothrow, unused, warn_unused_result, pure)
int libkeccak_spec_check(const libkeccak_spec_t* restrict spec)
{
long state_size = spec->capacity + spec->bitrate;
- long word_size = state_size / 25, n_word_size;
+ int_fast32_t word_size = (int_fast32_t)(state_size / 25);
if (spec->bitrate <= 0) return LIBKECCAK_SPEC_ERROR_BITRATE_NONPOSITIVE;
if (spec->bitrate % 8) return LIBKECCAK_SPEC_ERROR_BITRATE_MOD_8;
if (spec->capacity <= 0) return LIBKECCAK_SPEC_ERROR_CAPACITY_NONPOSITIVE;
@@ -177,10 +178,11 @@ int libkeccak_spec_check(const libkeccak_spec_t* restrict spec)
if (state_size % 25) return LIBKECCAK_SPEC_ERROR_STATE_MOD_25;
if (word_size % 8) return LIBKECCAK_SPEC_ERROR_WORD_MOD_8;
- /* This is a portable implementation of `(x & -x) != x` which assumes
- * two's complement, which of course is always satisfied by GCC, but anyway... */
- n_word_size = ((~word_size) ^ (LONG_MIN & ~LONG_MAX)) + 1;
- if ((word_size & n_word_size) != word_size)
+ /* `(x & -x) != x` assumes two's complement, which of course is always
+ * satisfied by GCC, however C99 guarantees that `int_fast32_t` exists,
+ * and it is basically the same thing as `long int`; with one important
+ * difference: it is guaranteed to use two's complement. */
+ if ((word_size & -word_size) != word_size)
return LIBKECCAK_SPEC_ERROR_WORD_NON_2_POTENT;
return 0;