diff options
Diffstat (limited to 'c')
-rw-r--r-- | c/sha3.c | 88 | ||||
-rw-r--r-- | c/sha3.h | 24 | ||||
-rw-r--r-- | c/sha3sum.c | 18 |
3 files changed, 94 insertions, 36 deletions
@@ -18,6 +18,8 @@ */ #include "sha3.h" +#include <string.h> + #ifdef WITH_C99 #define static_inline static inline @@ -421,19 +423,22 @@ static_inline llong sha3_toLane64(byte* restrict_ message, long msglen, long rr, * @param msg The message to pad * @param len The length of the message * @param r The bitrate + * @param bits The number of bits in the end of the message that does not make a whole byte * @param outlen The length of the padded message (out parameter) * @return The message padded */ -static_inline byte* sha3_pad10star1(byte* restrict_ msg, long len, long r, long* restrict_ outlen) +static_inline byte* sha3_pad10star1(byte* restrict_ msg, long len, long r, long bits, long* restrict_ outlen) { byte* message; + byte b; + long i, ll, nbrf, nrf; - long nrf = (len <<= 3) >> 3; - long nbrf = len & 7; - long ll = len % r; - long i; + len = ((len - (bits + 7) / 8) << 3) + bits; + nrf = len >> 3; + nbrf = len & 7; + ll = len % r; - byte b = (byte)(nbrf == 0 ? 1 : ((msg[nrf] >> (8 - nbrf)) | (1 << nbrf))); + b = (byte)(nbrf == 0 ? 1 : (msg[nrf] | (1 << nbrf))); if ((r - 8 <= ll) && (ll <= r - 2)) { @@ -591,7 +596,7 @@ extern void sha3_update(byte* restrict_ msg, long msglen) long nnn; if (mptr + msglen > mlen) - #ifdef WITH_WIPE + #ifndef WITH_WIPE M = (byte*)realloc(M, mlen = (mlen + msglen) << 1); #else { @@ -656,10 +661,12 @@ extern void sha3_update(byte* restrict_ msg, long msglen) * * @param msg The rest of the message, may be {@code null} * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by `msglen` + * @param suffix The suffix concatenate to the message * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false} */ -extern byte* sha3_digest(byte* restrict_ msg, long msglen, boolean withReturn) +extern byte* sha3_digest(byte* restrict_ msg, long msglen, long bits, char* restrict_ suffix, boolean withReturn) { byte* message; byte* _msg; @@ -669,28 +676,57 @@ extern byte* sha3_digest(byte* restrict_ msg, long msglen, boolean withReturn) long ww = w >> 3, ni; long i, j = 0, ptr = 0, _; long nnn; + long suffix_len = strlen(suffix); - if ((msg == null) || (msglen == 0)) - message = sha3_pad10star1(M, mptr, r, &len); - else + if (msg == null) + msglen = bits = 0; + + msglen += bits >> 3; + if ((bits &= 7)) { - if (mptr + msglen > mlen) - #ifdef WITH_WIPE - M = (byte*)realloc(M, mlen += msglen); - #else + msg[msglen] &= (1 << bits) - 1; + #ifndef WITH_WIPE + msg = (byte*)realloc(msg, msglen + ((suffix_len + bits + 7) >> 3)); + #else + { + char* old_msg = msg; + msg = (byte*)malloc(msglen + ((suffix_len + bits + 7) >> 3)); + memcpy(msg, old_msg, msglen + 1); + for (i = 0; i <= msglen; i++) + *(old_msg + i) = 0; + free(old_msg); + } + #endif + for (i = 0; i < suffix_len; i++) { - long mlen_ = mlen; - char* M_ = (byte*)malloc(mlen += msglen); - sha3_arraycopy(M, 0, M_, 0, mlen_); - for (i = 0; i < mlen_; i++) - *(M + i) = 0; - free(M); - M = M_; - } - #endif - sha3_arraycopy(msg, 0, M, mptr, msglen); - message = sha3_pad10star1(M, mptr + msglen, r, &len); + msg[msglen] |= (suffix[i] == '1') << bits; + if (bits == 8) + { + bits = 0; + msglen++; + } + } + if (bits) + msglen++; + } + + if (mptr + msglen > mlen) + #ifndef WITH_WIPE + M = (byte*)realloc(M, mlen += msglen); + #else + { + long mlen_ = mlen; + char* M_ = (byte*)malloc(mlen += msglen); + sha3_arraycopy(M, 0, M_, 0, mlen_); + for (i = 0; i < mlen_; i++) + *(M + i) = 0; + free(M); + M = M_; } + #endif + sha3_arraycopy(msg, 0, M, mptr, msglen); + message = sha3_pad10star1(M, mptr + msglen, r, bits, &len); + #ifdef WITH_WIPE for (i = 0; i < mlen; i++) *(M + i) = 0; @@ -42,6 +42,26 @@ #endif +/** + * Suffix the message when calculating the Keccak hash sum + */ +#define KECCAK_SUFFIX "" + +/** + * Suffix the message when calculating the SHA-3 hash sum + */ +#define SHA3_SUFFIX "01" + +/** + * Suffix the message when calculating the RawSHAKE hash sum + */ +#define RawSHAKE_SUFFIX "11" + +/** + * Suffix the message when calculating the SHAKE hash sum + */ +#define SHAKE_SUFFIX "1111" + /** * Initialise Keccak sponge @@ -73,10 +93,12 @@ extern void sha3_update(byte* restrict_ msg, long msglen); * * @param msg The rest of the message, may be {@code null} * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by `msglen` + * @param suffix The suffix concatenate to the message * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false} */ -extern byte* sha3_digest(byte* restrict_ msg, long msglen, boolean withReturn); +extern byte* sha3_digest(byte* restrict_ msg, long msglen, long bits, char* restrict_ suffix, boolean withReturn); /** diff --git a/c/sha3sum.c b/c/sha3sum.c index a0b5351..662933b 100644 --- a/c/sha3sum.c +++ b/c/sha3sum.c @@ -61,7 +61,7 @@ SET set_new() * * @param set The set */ -void set_free(SET restrict set) +void set_free(SET restrict_ set) { if (*(set + 0)) set_free((void**)*(set + 0)); if (*(set + 1)) set_free((void**)*(set + 1)); @@ -90,7 +90,7 @@ void set_free(SET restrict set) * @param item The item * @param n The length of the item */ -void set_add(SET restrict set, char* restrict item, long n) +void set_add(SET restrict_ set, char* restrict_ item, long n) { long i, j; void** at = set; @@ -125,7 +125,7 @@ void set_add(SET restrict set, char* restrict item, long n) * @param n The length of the item * @return Whether the set contains the item */ -long set_contains(SET restrict set, byte* restrict item, long n) +long set_contains(SET restrict_ set, byte* restrict_ item, long n) { long i; void** at = set; @@ -152,7 +152,7 @@ long set_contains(SET restrict set, byte* restrict item, long n) * @param b Second comparand * @return Whether the comparands are equal */ -long eq(char* restrict a, char* restrict b) +long eq(char* restrict_ a, char* restrict_ b) { while (*a) if (*a++ != *b++) @@ -167,7 +167,7 @@ long eq(char* restrict a, char* restrict b) * @param str String representation * @return Native representation */ -long parseInt(char* restrict str) +long parseInt(char* restrict_ str) { long rc = 0; while (*str) @@ -604,7 +604,7 @@ int main(int argc, char** argv) sha3_update(chunk, n); } } - bs = sha3_digest(null, 0, j == 1); + bs = sha3_digest(null, 0, 0, SHA3_SUFFIX, j == 1); if (j > 2) sha3_fastSqueeze(j - 2); if (j > 1) @@ -627,7 +627,7 @@ int main(int argc, char** argv) { byte* _bs = bs; sha3_initialise(r, c, o); - bs = sha3_digest(bs, bn, j == 1); + bs = sha3_digest(bs, bn, 0, SHA3_SUFFIX, j == 1); if (j > 2) sha3_fastSqueeze(j - 2); if (j > 1) @@ -670,7 +670,7 @@ int main(int argc, char** argv) { byte* _bs = bs; sha3_initialise(r, c, o); - bs = sha3_digest(bs, bn, j == 1); + bs = sha3_digest(bs, bn, 0, SHA3_SUFFIX, j == 1); if (j > 2) sha3_fastSqueeze(j - 2); if (j > 1) @@ -704,7 +704,7 @@ int main(int argc, char** argv) { byte* _bs = bs; sha3_initialise(r, c, o); - bs = sha3_digest(bs, bn, j == 1); + bs = sha3_digest(bs, bn, 0, SHA3_SUFFIX, j == 1); if (j > 2) sha3_fastSqueeze(j - 2); if (j > 1) |