diff options
-rw-r--r-- | src/libkeccak/spec.h | 12 |
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; |