diff options
author | Mattias Andrée <maandree@kth.se> | 2022-01-07 19:52:35 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2022-01-07 20:21:49 +0100 |
commit | 6adc0e6c6c378b5438533bdf55636ef049c1b956 (patch) | |
tree | ea55a4f54d7d190a1634c0a7ec8054fa2cdf47fd | |
parent | libblake_decode_hex: verify input (diff) | |
download | libblake-6adc0e6c6c378b5438533bdf55636ef049c1b956.tar.gz libblake-6adc0e6c6c378b5438533bdf55636ef049c1b956.tar.bz2 libblake-6adc0e6c6c378b5438533bdf55636ef049c1b956.tar.xz |
Add BLAKE2b and BLAKE2s + add salt support to BLAKE + m
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | common.h | 3 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | libblake.h | 63 | ||||
-rw-r--r-- | libblake_blake224_init.c | 11 | ||||
-rw-r--r-- | libblake_blake224_init2.c | 27 | ||||
-rw-r--r-- | libblake_blake256_init.c | 11 | ||||
-rw-r--r-- | libblake_blake256_init2.c | 27 | ||||
-rw-r--r-- | libblake_blake2b_digest.c | 59 | ||||
-rw-r--r-- | libblake_blake2b_digest_get_required_input_size.c | 13 | ||||
-rw-r--r-- | libblake_blake2b_init.c | 83 | ||||
-rw-r--r-- | libblake_blake2b_update.c | 19 | ||||
-rw-r--r-- | libblake_blake2s_digest.c | 47 | ||||
-rw-r--r-- | libblake_blake2s_digest_get_required_input_size.c | 13 | ||||
-rw-r--r-- | libblake_blake2s_init.c | 58 | ||||
-rw-r--r-- | libblake_blake2s_update.c | 19 | ||||
-rw-r--r-- | libblake_blake384_init.c | 11 | ||||
-rw-r--r-- | libblake_blake384_init2.c | 31 | ||||
-rw-r--r-- | libblake_blake512_init.c | 11 | ||||
-rw-r--r-- | libblake_blake512_init2.c | 31 | ||||
-rw-r--r-- | libblake_internal_blake2b_compress.c | 103 | ||||
-rw-r--r-- | libblake_internal_blake2s_compress.c | 97 | ||||
-rw-r--r-- | libblake_internal_blakeb_update.c | 40 | ||||
-rw-r--r-- | libblake_internal_blakes_update.c | 40 | ||||
-rw-r--r-- | test.c | 146 |
25 files changed, 900 insertions, 84 deletions
@@ -20,28 +20,45 @@ OBJ_BLAKE =\ libblake_blake224_digest.o\ libblake_blake224_digest_get_required_input_size.o\ libblake_blake224_init.o\ + libblake_blake224_init2.o\ libblake_blake224_update.o\ libblake_blake256_digest.o\ libblake_blake256_digest_get_required_input_size.o\ libblake_blake256_init.o\ + libblake_blake256_init2.o\ libblake_blake256_update.o\ libblake_blake384_digest.o\ libblake_blake384_digest_get_required_input_size.o\ libblake_blake384_init.o\ + libblake_blake384_init2.o\ libblake_blake384_update.o\ libblake_blake512_digest.o\ libblake_blake512_digest_get_required_input_size.o\ libblake_blake512_init.o\ + libblake_blake512_init2.o\ libblake_blake512_update.o\ libblake_internal_blakeb_digest.o\ libblake_internal_blakes_digest.o\ libblake_internal_blakeb_update.o\ libblake_internal_blakes_update.o +OBJ_BLAKE2 =\ + libblake_blake2b_digest.o\ + libblake_blake2s_digest.o\ + libblake_blake2b_digest_get_required_input_size.o\ + libblake_blake2s_digest_get_required_input_size.o\ + libblake_blake2b_init.o\ + libblake_blake2s_init.o\ + libblake_blake2b_update.o\ + libblake_blake2s_update.o\ + libblake_internal_blake2b_compress.o\ + libblake_internal_blake2s_compress.o + OBJ =\ libblake_encode_hex.o\ libblake_decode_hex.o\ - $(OBJ_BLAKE) + $(OBJ_BLAKE)\ + $(OBJ_BLAKE2) HDR =\ libblake.h @@ -26,3 +26,6 @@ HIDDEN void libblake_internal_blakes_digest(struct libblake_blakes_state *state, size_t bits, const char *suffix, unsigned char *output, size_t words_out); HIDDEN void libblake_internal_blakeb_digest(struct libblake_blakeb_state *state, unsigned char *data, size_t len, size_t bits, const char *suffix, unsigned char *output, size_t words_out); + +HIDDEN void libblake_internal_blake2s_compress(struct libblake_blake2s_state *state, const unsigned char *data); +HIDDEN void libblake_internal_blake2b_compress(struct libblake_blake2b_state *state, const unsigned char *data); @@ -4,5 +4,5 @@ MANPREFIX = $(PREFIX)/share/man CC = c99 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -CFLAGS = -Wall -O2 +CFLAGS = -Wall -O3 LDFLAGS = -s @@ -7,13 +7,17 @@ #if defined(__GNUC__) # define LIBBLAKE_PURE__ __attribute__((__pure__)) +# define LIBBLAKE_CONST__ __attribute__((__const__)) #else # define LIBBLAKE_PURE__ +# define LIBBLAKE_CONST__ #endif + void libblake_encode_hex(const void *data, size_t n, char out[/* static n * 2 + 1 */], int uppercase); size_t libblake_decode_hex(const char *data, size_t n, void *out, int *validp); + #define LIBBLAKE_BLAKE224_OUTPUT_SIZE (224 / 8) #define LIBBLAKE_BLAKE256_OUTPUT_SIZE (256 / 8) #define LIBBLAKE_BLAKE384_OUTPUT_SIZE (384 / 8) @@ -37,27 +41,86 @@ struct libblake_blake384_state { struct libblake_blakeb_state b; }; struct libblake_blake512_state { struct libblake_blakeb_state b; }; void libblake_blake224_init(struct libblake_blake224_state *state); +void libblake_blake224_init2(struct libblake_blake224_state *state, uint_least8_t salt[16]); size_t libblake_blake224_update(struct libblake_blake224_state *state, const void *data, size_t len); void libblake_blake224_digest(struct libblake_blake224_state *state, void *data, size_t len, size_t bits, const char *suffix, unsigned char output[static LIBBLAKE_BLAKE224_OUTPUT_SIZE]); LIBBLAKE_PURE__ size_t libblake_blake224_digest_get_required_input_size(size_t len, size_t bits, const char *suffix); void libblake_blake256_init(struct libblake_blake256_state *state); +void libblake_blake256_init2(struct libblake_blake256_state *state, uint_least8_t salt[16]); size_t libblake_blake256_update(struct libblake_blake256_state *state, const void *data, size_t len); void libblake_blake256_digest(struct libblake_blake256_state *state, void *data, size_t len, size_t bits, const char *suffix, unsigned char output[static LIBBLAKE_BLAKE256_OUTPUT_SIZE]); LIBBLAKE_PURE__ size_t libblake_blake256_digest_get_required_input_size(size_t len, size_t bits, const char *suffix); void libblake_blake384_init(struct libblake_blake384_state *state); +void libblake_blake384_init2(struct libblake_blake384_state *state, uint_least8_t salt[32]); size_t libblake_blake384_update(struct libblake_blake384_state *state, const void *data, size_t len); void libblake_blake384_digest(struct libblake_blake384_state *state, void *data, size_t len, size_t bits, const char *suffix, unsigned char output[static LIBBLAKE_BLAKE384_OUTPUT_SIZE]); LIBBLAKE_PURE__ size_t libblake_blake384_digest_get_required_input_size(size_t len, size_t bits, const char *suffix); void libblake_blake512_init(struct libblake_blake512_state *state); +void libblake_blake512_init2(struct libblake_blake512_state *state, uint_least8_t salt[32]); size_t libblake_blake512_update(struct libblake_blake512_state *state, const void *data, size_t len); void libblake_blake512_digest(struct libblake_blake512_state *state, void *data, size_t len, size_t bits, const char *suffix, unsigned char output[static LIBBLAKE_BLAKE512_OUTPUT_SIZE]); LIBBLAKE_PURE__ size_t libblake_blake512_digest_get_required_input_size(size_t len, size_t bits, const char *suffix); + +struct libblake_blake2s_params { + uint_least8_t digest_len; /* in bytes, [1, 32] */ + uint_least8_t key_len; /* in bytes, [0, 32] */ + uint_least8_t fanout; /* normally 1 */ + uint_least8_t depth; /* normally 1 */ + uint_least32_t leaf_len; + uint_least32_t node_offset; + uint_least16_t xof_len; + uint_least8_t node_depth; + uint_least8_t inner_len; + uint_least8_t salt[8]; + uint_least8_t pepper[8]; +}; + +struct libblake_blake2b_params { + uint_least8_t digest_len; /* in bytes, [1, 64] */ + uint_least8_t key_len; /* in bytes, [0, 64] */ + uint_least8_t fanout; /* normally 1 */ + uint_least8_t depth; /* normally 1 */ + uint_least32_t leaf_len; + uint_least32_t node_offset; + uint_least32_t xof_len; + uint_least8_t node_depth; + uint_least8_t inner_len; + uint_least8_t salt[16]; + uint_least8_t pepper[16]; +}; + +struct libblake_blake2s_state { + uint_least32_t h[8]; + uint_least32_t t[2]; + uint_least32_t f[2]; +}; + +struct libblake_blake2b_state { + uint_least64_t h[8]; + uint_least64_t t[2]; + uint_least64_t f[2]; +}; + +void libblake_blake2s_init(struct libblake_blake2s_state *state, const struct libblake_blake2s_params *params, + const unsigned char *key /* append null bytes until 64 bytes; if key is used */); +size_t libblake_blake2s_update(struct libblake_blake2s_state *state, const void *data, size_t len); +void libblake_blake2s_digest(struct libblake_blake2s_state *state, void *data, size_t len, + size_t output_len, unsigned char output[static output_len]); +LIBBLAKE_CONST__ size_t libblake_blake2s_digest_get_required_input_size(size_t len); + +void libblake_blake2b_init(struct libblake_blake2b_state *state, const struct libblake_blake2b_params *params, + const unsigned char *key /* append null bytes until 128 bytes; if key is used */); +size_t libblake_blake2b_update(struct libblake_blake2b_state *state, const void *data, size_t len); +void libblake_blake2b_digest(struct libblake_blake2b_state *state, void *data, size_t len, + size_t output_len, unsigned char output[static output_len]); +LIBBLAKE_CONST__ size_t libblake_blake2b_digest_get_required_input_size(size_t len); + #endif diff --git a/libblake_blake224_init.c b/libblake_blake224_init.c index 0eb67e0..f133887 100644 --- a/libblake_blake224_init.c +++ b/libblake_blake224_init.c @@ -4,14 +4,5 @@ void libblake_blake224_init(struct libblake_blake224_state *state) { - state->s.h[0] = UINT_LEAST32_C(0xC1059ED8); - state->s.h[1] = UINT_LEAST32_C(0x367CD507); - state->s.h[2] = UINT_LEAST32_C(0x3070DD17); - state->s.h[3] = UINT_LEAST32_C(0xF70E5939); - state->s.h[4] = UINT_LEAST32_C(0xFFC00B31); - state->s.h[5] = UINT_LEAST32_C(0x68581511); - state->s.h[6] = UINT_LEAST32_C(0x64F98FA7); - state->s.h[7] = UINT_LEAST32_C(0xBEFA4FA4); - memset(state->s.s, 0, sizeof(state->s.s)); - memset(state->s.t, 0, sizeof(state->s.t)); + libblake_blake224_init2(state, NULL); } diff --git a/libblake_blake224_init2.c b/libblake_blake224_init2.c new file mode 100644 index 0000000..c67eff1 --- /dev/null +++ b/libblake_blake224_init2.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +void +libblake_blake224_init2(struct libblake_blake224_state *state, uint_least8_t salt[16]) +{ + size_t i; + state->s.h[0] = UINT_LEAST32_C(0xC1059ED8); + state->s.h[1] = UINT_LEAST32_C(0x367CD507); + state->s.h[2] = UINT_LEAST32_C(0x3070DD17); + state->s.h[3] = UINT_LEAST32_C(0xF70E5939); + state->s.h[4] = UINT_LEAST32_C(0xFFC00B31); + state->s.h[5] = UINT_LEAST32_C(0x68581511); + state->s.h[6] = UINT_LEAST32_C(0x64F98FA7); + state->s.h[7] = UINT_LEAST32_C(0xBEFA4FA4); + if (!salt) { + memset(state->s.s, 0, sizeof(state->s.s)); + } else { + for (i = 0; i < 4; i++) { + state->s.s[i] = ((uint_least32_t)(salt[i * 4 + 0] & 255) << 24) + | ((uint_least32_t)(salt[i * 4 + 1] & 255) << 16) + | ((uint_least32_t)(salt[i * 4 + 2] & 255) << 8) + | ((uint_least32_t)(salt[i * 4 + 3] & 255) << 0); + } + } + memset(state->s.t, 0, sizeof(state->s.t)); +} diff --git a/libblake_blake256_init.c b/libblake_blake256_init.c index 2a95b8d..78d1978 100644 --- a/libblake_blake256_init.c +++ b/libblake_blake256_init.c @@ -4,14 +4,5 @@ void libblake_blake256_init(struct libblake_blake256_state *state) { - state->s.h[0] = UINT_LEAST32_C(0x6A09E667); - state->s.h[1] = UINT_LEAST32_C(0xBB67AE85); - state->s.h[2] = UINT_LEAST32_C(0x3C6EF372); - state->s.h[3] = UINT_LEAST32_C(0xA54FF53A); - state->s.h[4] = UINT_LEAST32_C(0x510E527F); - state->s.h[5] = UINT_LEAST32_C(0x9B05688C); - state->s.h[6] = UINT_LEAST32_C(0x1F83D9AB); - state->s.h[7] = UINT_LEAST32_C(0x5BE0CD19); - memset(state->s.s, 0, sizeof(state->s.s)); - memset(state->s.t, 0, sizeof(state->s.t)); + libblake_blake256_init2(state, NULL); } diff --git a/libblake_blake256_init2.c b/libblake_blake256_init2.c new file mode 100644 index 0000000..271df7d --- /dev/null +++ b/libblake_blake256_init2.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +void +libblake_blake256_init2(struct libblake_blake256_state *state, uint_least8_t salt[16]) +{ + size_t i; + state->s.h[0] = UINT_LEAST32_C(0x6A09E667); + state->s.h[1] = UINT_LEAST32_C(0xBB67AE85); + state->s.h[2] = UINT_LEAST32_C(0x3C6EF372); + state->s.h[3] = UINT_LEAST32_C(0xA54FF53A); + state->s.h[4] = UINT_LEAST32_C(0x510E527F); + state->s.h[5] = UINT_LEAST32_C(0x9B05688C); + state->s.h[6] = UINT_LEAST32_C(0x1F83D9AB); + state->s.h[7] = UINT_LEAST32_C(0x5BE0CD19); + if (!salt) { + memset(state->s.s, 0, sizeof(state->s.s)); + } else { + for (i = 0; i < 4; i++) { + state->s.s[i] = ((uint_least32_t)(salt[i * 4 + 0] & 255) << 24) + | ((uint_least32_t)(salt[i * 4 + 1] & 255) << 16) + | ((uint_least32_t)(salt[i * 4 + 2] & 255) << 8) + | ((uint_least32_t)(salt[i * 4 + 3] & 255) << 0); + } + } + memset(state->s.t, 0, sizeof(state->s.t)); +} diff --git a/libblake_blake2b_digest.c b/libblake_blake2b_digest.c new file mode 100644 index 0000000..f1e45a8 --- /dev/null +++ b/libblake_blake2b_digest.c @@ -0,0 +1,59 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +static void +encode_uint64_le(unsigned char *out, uint_least64_t value, size_t bytes) +{ + switch (bytes) { + default: + out[7] = (unsigned char)((value >> 56) & 255); + /* fall through */ + case 7: + out[6] = (unsigned char)((value >> 48) & 255); + /* fall through */ + case 6: + out[5] = (unsigned char)((value >> 40) & 255); + /* fall through */ + case 5: + out[4] = (unsigned char)((value >> 32) & 255); + /* fall through */ + case 4: + out[3] = (unsigned char)((value >> 24) & 255); + /* fall through */ + case 3: + out[2] = (unsigned char)((value >> 16) & 255); + /* fall through */ + case 2: + out[1] = (unsigned char)((value >> 8) & 255); + /* fall through */ + case 1: + out[0] = (unsigned char)((value >> 0) & 255); + /* fall through */ + case 0: + break; + } +} + +void +libblake_blake2b_digest(struct libblake_blake2b_state *state, void *data_, size_t len, + size_t output_len, unsigned char output[static output_len]) +{ + unsigned char *data = data_; + size_t r, i, j; + + r = libblake_blake2b_update(state, data, len); + data = &data[r]; + len -= r; + + state->f[0] = UINT_LEAST64_C(0xFFFFffffFFFFffff); + memset(&data[len], 0, 128 - len); + + state->t[0] = (state->t[0] + len) & UINT_LEAST64_C(0xFFFFffffFFFFffff); + if (state->t[0] < len) + state->t[1] = (state->t[1] + 1) & UINT_LEAST64_C(0xFFFFffffFFFFffff); + + libblake_internal_blake2b_compress(state, data); + + for (i = 0, j = 0; i < output_len; i += 8, j += 1) + encode_uint64_le(&output[i], state->h[j], output_len - i); +} diff --git a/libblake_blake2b_digest_get_required_input_size.c b/libblake_blake2b_digest_get_required_input_size.c new file mode 100644 index 0000000..12288df --- /dev/null +++ b/libblake_blake2b_digest_get_required_input_size.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +size_t +libblake_blake2b_digest_get_required_input_size(size_t len) +{ + size_t blocks, rem; + blocks = len >> 7; + rem = len & 127; + if (rem) + blocks += 1; + return blocks << 7; +} diff --git a/libblake_blake2b_init.c b/libblake_blake2b_init.c new file mode 100644 index 0000000..7de9bb2 --- /dev/null +++ b/libblake_blake2b_init.c @@ -0,0 +1,83 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +#define A 10 +#define B 11 +#define C 12 +#define D 13 +#define E 14 +#define F 15 + +void +libblake_blake2b_init(struct libblake_blake2b_state *state, const struct libblake_blake2b_params *params, const unsigned char *key) +{ + state->h[0] = UINT_LEAST64_C(0x6A09E667F3BCC908); + state->h[1] = UINT_LEAST64_C(0xBB67AE8584CAA73B); + state->h[2] = UINT_LEAST64_C(0x3C6EF372FE94F82B); + state->h[3] = UINT_LEAST64_C(0xA54FF53A5F1D36F1); + state->h[4] = UINT_LEAST64_C(0x510E527FADE682D1); + state->h[5] = UINT_LEAST64_C(0x9B05688C2B3E6C1F); + state->h[6] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B); + state->h[7] = UINT_LEAST64_C(0x5BE0CD19137E2179); + + state->t[0] = 0; + state->t[1] = 0; + state->f[0] = 0; + state->f[1] = 0; + + state->h[0] ^= ((uint_least64_t)params->digest_len & 255) << 0; + state->h[0] ^= ((uint_least64_t)params->key_len & 255) << 8; + state->h[0] ^= ((uint_least64_t)params->fanout & 255) << 16; + state->h[0] ^= ((uint_least64_t)params->depth & 255) << 24; + state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 0) & 255) << 32; + state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 8) & 255) << 40; + state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 16) & 255) << 48; + state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 24) & 255) << 56; + state->h[1] ^= ((uint_least64_t)(params->node_offset >> 0) & 255) << 0; + state->h[1] ^= ((uint_least64_t)(params->node_offset >> 8) & 255) << 8; + state->h[1] ^= ((uint_least64_t)(params->node_offset >> 16) & 255) << 16; + state->h[1] ^= ((uint_least64_t)(params->node_offset >> 24) & 255) << 24; + state->h[1] ^= ((uint_least64_t)(params->xof_len >> 0) & 255) << 32; + state->h[1] ^= ((uint_least64_t)(params->xof_len >> 8) & 255) << 40; + state->h[1] ^= ((uint_least64_t)(params->xof_len >> 16) & 255) << 48; + state->h[1] ^= ((uint_least64_t)(params->xof_len >> 24) & 255) << 56; + state->h[2] ^= ((uint_least64_t)params->node_depth & 255) << 0; + state->h[2] ^= ((uint_least64_t)params->inner_len & 255) << 8; + state->h[4] ^= ((uint_least64_t)params->salt[0] & 255) << 0; + state->h[4] ^= ((uint_least64_t)params->salt[1] & 255) << 8; + state->h[4] ^= ((uint_least64_t)params->salt[2] & 255) << 16; + state->h[4] ^= ((uint_least64_t)params->salt[3] & 255) << 24; + state->h[4] ^= ((uint_least64_t)params->salt[4] & 255) << 32; + state->h[4] ^= ((uint_least64_t)params->salt[5] & 255) << 40; + state->h[4] ^= ((uint_least64_t)params->salt[6] & 255) << 48; + state->h[4] ^= ((uint_least64_t)params->salt[7] & 255) << 56; + state->h[5] ^= ((uint_least64_t)params->salt[8] & 255) << 0; + state->h[5] ^= ((uint_least64_t)params->salt[9] & 255) << 8; + state->h[5] ^= ((uint_least64_t)params->salt[A] & 255) << 16; + state->h[5] ^= ((uint_least64_t)params->salt[B] & 255) << 24; + state->h[5] ^= ((uint_least64_t)params->salt[C] & 255) << 32; + state->h[5] ^= ((uint_least64_t)params->salt[D] & 255) << 40; + state->h[5] ^= ((uint_least64_t)params->salt[E] & 255) << 48; + state->h[5] ^= ((uint_least64_t)params->salt[F] & 255) << 56; + state->h[6] ^= ((uint_least64_t)params->pepper[0] & 255) << 0; + state->h[6] ^= ((uint_least64_t)params->pepper[1] & 255) << 8; + state->h[6] ^= ((uint_least64_t)params->pepper[2] & 255) << 16; + state->h[6] ^= ((uint_least64_t)params->pepper[3] & 255) << 24; + state->h[6] ^= ((uint_least64_t)params->pepper[4] & 255) << 32; + state->h[6] ^= ((uint_least64_t)params->pepper[5] & 255) << 40; + state->h[6] ^= ((uint_least64_t)params->pepper[6] & 255) << 48; + state->h[6] ^= ((uint_least64_t)params->pepper[7] & 255) << 56; + state->h[7] ^= ((uint_least64_t)params->pepper[8] & 255) << 0; + state->h[7] ^= ((uint_least64_t)params->pepper[9] & 255) << 8; + state->h[7] ^= ((uint_least64_t)params->pepper[A] & 255) << 16; + state->h[7] ^= ((uint_least64_t)params->pepper[B] & 255) << 24; + state->h[7] ^= ((uint_least64_t)params->pepper[C] & 255) << 32; + state->h[7] ^= ((uint_least64_t)params->pepper[D] & 255) << 40; + state->h[7] ^= ((uint_least64_t)params->pepper[E] & 255) << 48; + state->h[7] ^= ((uint_least64_t)params->pepper[F] & 255) << 56; + + if (params->key_len) { + state->t[0] = 128; + libblake_internal_blake2b_compress(state, key); + } +} diff --git a/libblake_blake2b_update.c b/libblake_blake2b_update.c new file mode 100644 index 0000000..cbd38f2 --- /dev/null +++ b/libblake_blake2b_update.c @@ -0,0 +1,19 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +size_t +libblake_blake2b_update(struct libblake_blake2b_state *state, const void *data_, size_t len) +{ + const unsigned char *data = data_; + size_t off = 0; + + for (; len - off > 128; off += 128) { + state->t[0] = (state->t[0] + 128) & UINT_LEAST64_C(0xFFFFffffFFFFffff); + if (state->t[0] < 128) + state->t[1] = (state->t[1] + 1) & UINT_LEAST64_C(0xFFFFffffFFFFffff); + + libblake_internal_blake2b_compress(state, &data[off]); + } + + return off; +} diff --git a/libblake_blake2s_digest.c b/libblake_blake2s_digest.c new file mode 100644 index 0000000..d9106a5 --- /dev/null +++ b/libblake_blake2s_digest.c @@ -0,0 +1,47 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +static void +encode_uint32_le(unsigned char *out, uint_least32_t value, size_t bytes) +{ + switch (bytes) { + default: + out[3] = (unsigned char)((value >> 24) & 255); + /* fall through */ + case 3: + out[2] = (unsigned char)((value >> 16) & 255); + /* fall through */ + case 2: + out[1] = (unsigned char)((value >> 8) & 255); + /* fall through */ + case 1: + out[0] = (unsigned char)((value >> 0) & 255); + /* fall through */ + case 0: + break; + } +} + +void +libblake_blake2s_digest(struct libblake_blake2s_state *state, void *data_, size_t len, + size_t output_len, unsigned char output[static output_len]) +{ + unsigned char *data = data_; + size_t r, i, j; + + r = libblake_blake2s_update(state, data, len); + data = &data[r]; + len -= r; + + state->f[0] = UINT_LEAST32_C(0xFFFFffff); + memset(&data[len], 0, 64 - len); + + state->t[0] = (state->t[0] + len) & UINT_LEAST32_C(0xFFFFffff); + if (state->t[0] < len) + state->t[1] = (state->t[1] + 1) & UINT_LEAST32_C(0xFFFFffff); + + libblake_internal_blake2s_compress(state, data); + + for (i = 0, j = 0; i < output_len; i += 4, j += 1) + encode_uint32_le(&output[i], state->h[j], output_len - i); +} diff --git a/libblake_blake2s_digest_get_required_input_size.c b/libblake_blake2s_digest_get_required_input_size.c new file mode 100644 index 0000000..c356822 --- /dev/null +++ b/libblake_blake2s_digest_get_required_input_size.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +size_t +libblake_blake2s_digest_get_required_input_size(size_t len) +{ + size_t blocks, rem; + blocks = len >> 6; + rem = len & 63; + if (rem) + blocks += 1; + return blocks << 6; +} diff --git a/libblake_blake2s_init.c b/libblake_blake2s_init.c new file mode 100644 index 0000000..d33ce5c --- /dev/null +++ b/libblake_blake2s_init.c @@ -0,0 +1,58 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +void +libblake_blake2s_init(struct libblake_blake2s_state *state, const struct libblake_blake2s_params *params, const unsigned char *key) +{ + state->h[0] = UINT_LEAST32_C(0x6A09E667); + state->h[1] = UINT_LEAST32_C(0xBB67AE85); + state->h[2] = UINT_LEAST32_C(0x3C6EF372); + state->h[3] = UINT_LEAST32_C(0xA54FF53A); + state->h[4] = UINT_LEAST32_C(0x510E527F); + state->h[5] = UINT_LEAST32_C(0x9B05688C); + state->h[6] = UINT_LEAST32_C(0x1F83D9AB); + state->h[7] = UINT_LEAST32_C(0x5BE0CD19); + + state->t[0] = 0; + state->t[1] = 0; + state->f[0] = 0; + state->f[1] = 0; + + state->h[0] ^= ((uint_least32_t)params->digest_len & 255) << 0; + state->h[0] ^= ((uint_least32_t)params->key_len & 255) << 8; + state->h[0] ^= ((uint_least32_t)params->fanout & 255) << 16; + state->h[0] ^= ((uint_least32_t)params->depth & 255) << 24; + state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 0) & 255) << 0; + state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 8) & 255) << 8; + state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 16) & 255) << 16; + state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 24) & 255) << 24; + state->h[2] ^= ((uint_least32_t)(params->node_offset >> 0) & 255) << 0; + state->h[2] ^= ((uint_least32_t)(params->node_offset >> 8) & 255) << 8; + state->h[2] ^= ((uint_least32_t)(params->node_offset >> 16) & 255) << 16; + state->h[2] ^= ((uint_least32_t)(params->node_offset >> 24) & 255) << 24; + state->h[3] ^= ((uint_least32_t)(params->xof_len >> 0) & 255) << 0; + state->h[3] ^= ((uint_least32_t)(params->xof_len >> 8) & 255) << 8; + state->h[3] ^= ((uint_least32_t)params->node_depth & 255) << 16; + state->h[3] ^= ((uint_least32_t)params->inner_len & 255) << 24; + state->h[4] ^= ((uint_least32_t)params->salt[0] & 255) << 0; + state->h[4] ^= ((uint_least32_t)params->salt[1] & 255) << 8; + state->h[4] ^= ((uint_least32_t)params->salt[2] & 255) << 16; + state->h[4] ^= ((uint_least32_t)params->salt[3] & 255) << 24; + state->h[5] ^= ((uint_least32_t)params->salt[4] & 255) << 0; + state->h[5] ^= ((uint_least32_t)params->salt[5] & 255) << 8; + state->h[5] ^= ((uint_least32_t)params->salt[6] & 255) << 16; + state->h[5] ^= ((uint_least32_t)params->salt[7] & 255) << 24; + state->h[6] ^= ((uint_least32_t)params->pepper[0] & 255) << 0; + state->h[6] ^= ((uint_least32_t)params->pepper[1] & 255) << 8; + state->h[6] ^= ((uint_least32_t)params->pepper[2] & 255) << 16; + state->h[6] ^= ((uint_least32_t)params->pepper[3] & 255) << 24; + state->h[7] ^= ((uint_least32_t)params->pepper[4] & 255) << 0; + state->h[7] ^= ((uint_least32_t)params->pepper[5] & 255) << 8; + state->h[7] ^= ((uint_least32_t)params->pepper[6] & 255) << 16; + state->h[7] ^= ((uint_least32_t)params->pepper[7] & 255) << 24; + + if (params->key_len) { + state->t[0] = 32; + libblake_internal_blake2s_compress(state, key); + } +} diff --git a/libblake_blake2s_update.c b/libblake_blake2s_update.c new file mode 100644 index 0000000..598260f --- /dev/null +++ b/libblake_blake2s_update.c @@ -0,0 +1,19 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +size_t +libblake_blake2s_update(struct libblake_blake2s_state *state, const void *data_, size_t len) +{ + const unsigned char *data = data_; + size_t off = 0; + + for (; len - off > 64; off += 64) { + state->t[0] = (state->t[0] + 64) & UINT_LEAST32_C(0xFFFFffff); + if (state->t[0] < 64) + state->t[1] = (state->t[1] + 1) & UINT_LEAST32_C(0xFFFFffff); + + libblake_internal_blake2s_compress(state, &data[off]); + } + + return off; +} diff --git a/libblake_blake384_init.c b/libblake_blake384_init.c index b7529f3..a08509a 100644 --- a/libblake_blake384_init.c +++ b/libblake_blake384_init.c @@ -4,14 +4,5 @@ void libblake_blake384_init(struct libblake_blake384_state *state) { - state->b.h[0] = UINT_LEAST64_C(0xCBBB9D5DC1059ED8); - state->b.h[1] = UINT_LEAST64_C(0x629A292A367CD507); - state->b.h[2] = UINT_LEAST64_C(0x9159015A3070DD17); - state->b.h[3] = UINT_LEAST64_C(0x152FECD8F70E5939); - state->b.h[4] = UINT_LEAST64_C(0x67332667FFC00B31); - state->b.h[5] = UINT_LEAST64_C(0x8EB44A8768581511); - state->b.h[6] = UINT_LEAST64_C(0xDB0C2E0D64F98FA7); - state->b.h[7] = UINT_LEAST64_C(0x47B5481DBEFA4FA4); - memset(state->b.s, 0, sizeof(state->b.s)); - memset(state->b.t, 0, sizeof(state->b.t)); + libblake_blake384_init2(state, NULL); } diff --git a/libblake_blake384_init2.c b/libblake_blake384_init2.c new file mode 100644 index 0000000..1ea2137 --- /dev/null +++ b/libblake_blake384_init2.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +void +libblake_blake384_init2(struct libblake_blake384_state *state, uint_least8_t salt[32]) +{ + size_t i; + state->b.h[0] = UINT_LEAST64_C(0xCBBB9D5DC1059ED8); + state->b.h[1] = UINT_LEAST64_C(0x629A292A367CD507); + state->b.h[2] = UINT_LEAST64_C(0x9159015A3070DD17); + state->b.h[3] = UINT_LEAST64_C(0x152FECD8F70E5939); + state->b.h[4] = UINT_LEAST64_C(0x67332667FFC00B31); + state->b.h[5] = UINT_LEAST64_C(0x8EB44A8768581511); + state->b.h[6] = UINT_LEAST64_C(0xDB0C2E0D64F98FA7); + state->b.h[7] = UINT_LEAST64_C(0x47B5481DBEFA4FA4); + if (!salt) { + memset(state->b.s, 0, sizeof(state->b.s)); + } else { + for (i = 0; i < 4; i++) { + state->b.s[i] = ((uint_least64_t)(salt[i * 8 + 0] & 255) << 56) + | ((uint_least64_t)(salt[i * 8 + 1] & 255) << 48) + | ((uint_least64_t)(salt[i * 8 + 2] & 255) << 40) + | ((uint_least64_t)(salt[i * 8 + 3] & 255) << 32) + | ((uint_least64_t)(salt[i * 8 + 4] & 255) << 24) + | ((uint_least64_t)(salt[i * 8 + 5] & 255) << 16) + | ((uint_least64_t)(salt[i * 8 + 6] & 255) << 8) + | ((uint_least64_t)(salt[i * 8 + 7] & 255) << 0); + } + } + memset(state->b.t, 0, sizeof(state->b.t)); +} diff --git a/libblake_blake512_init.c b/libblake_blake512_init.c index 85d011f..e45fb9e 100644 --- a/libblake_blake512_init.c +++ b/libblake_blake512_init.c @@ -4,14 +4,5 @@ void libblake_blake512_init(struct libblake_blake512_state *state) { - state->b.h[0] = UINT_LEAST64_C(0x6A09E667F3BCC908); - state->b.h[1] = UINT_LEAST64_C(0xBB67AE8584CAA73B); - state->b.h[2] = UINT_LEAST64_C(0x3C6EF372FE94F82B); - state->b.h[3] = UINT_LEAST64_C(0xA54FF53A5F1D36F1); - state->b.h[4] = UINT_LEAST64_C(0x510E527FADE682D1); - state->b.h[5] = UINT_LEAST64_C(0x9B05688C2B3E6C1F); - state->b.h[6] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B); - state->b.h[7] = UINT_LEAST64_C(0x5BE0CD19137E2179); - memset(state->b.s, 0, sizeof(state->b.s)); - memset(state->b.t, 0, sizeof(state->b.t)); + libblake_blake512_init2(state, NULL); } diff --git a/libblake_blake512_init2.c b/libblake_blake512_init2.c new file mode 100644 index 0000000..5363e7f --- /dev/null +++ b/libblake_blake512_init2.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +void +libblake_blake512_init2(struct libblake_blake512_state *state, uint_least8_t salt[32]) +{ + size_t i; + state->b.h[0] = UINT_LEAST64_C(0x6A09E667F3BCC908); + state->b.h[1] = UINT_LEAST64_C(0xBB67AE8584CAA73B); + state->b.h[2] = UINT_LEAST64_C(0x3C6EF372FE94F82B); + state->b.h[3] = UINT_LEAST64_C(0xA54FF53A5F1D36F1); + state->b.h[4] = UINT_LEAST64_C(0x510E527FADE682D1); + state->b.h[5] = UINT_LEAST64_C(0x9B05688C2B3E6C1F); + state->b.h[6] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B); + state->b.h[7] = UINT_LEAST64_C(0x5BE0CD19137E2179); + if (!salt) { + memset(state->b.s, 0, sizeof(state->b.s)); + } else { + for (i = 0; i < 4; i++) { + state->b.s[i] = ((uint_least64_t)(salt[i * 8 + 0] & 255) << 56) + | ((uint_least64_t)(salt[i * 8 + 1] & 255) << 48) + | ((uint_least64_t)(salt[i * 8 + 2] & 255) << 40) + | ((uint_least64_t)(salt[i * 8 + 3] & 255) << 32) + | ((uint_least64_t)(salt[i * 8 + 4] & 255) << 24) + | ((uint_least64_t)(salt[i * 8 + 5] & 255) << 16) + | ((uint_least64_t)(salt[i * 8 + 6] & 255) << 8) + | ((uint_least64_t)(salt[i * 8 + 7] & 255) << 0); + } + } + memset(state->b.t, 0, sizeof(state->b.t)); +} diff --git a/libblake_internal_blake2b_compress.c b/libblake_internal_blake2b_compress.c new file mode 100644 index 0000000..eab4b44 --- /dev/null +++ b/libblake_internal_blake2b_compress.c @@ -0,0 +1,103 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +#define A 10 +#define B 11 +#define C 12 +#define D 13 +#define E 14 +#define F 15 + +static uint_least64_t +decode_uint64_le(const unsigned char *data) +{ + return (((uint_least64_t)(data[0] & 255)) << 0) | + (((uint_least64_t)(data[1] & 255)) << 8) | + (((uint_least64_t)(data[2] & 255)) << 16) | + (((uint_least64_t)(data[3] & 255)) << 24) | + (((uint_least64_t)(data[4] & 255)) << 32) | + (((uint_least64_t)(data[5] & 255)) << 40) | + (((uint_least64_t)(data[6] & 255)) << 48) | + (((uint_least64_t)(data[7] & 255)) << 56); +} + +static uint_least64_t +rotate_right(uint_least64_t x, int n) +{ + return ((x >> n) | (x << (64 - n))) & UINT_LEAST64_C(0xFFFFffffFFFFffff); +} + +void +libblake_internal_blake2b_compress(struct libblake_blake2b_state *state, const unsigned char *data) +{ + uint_least64_t v[16], m[16]; + + memcpy(v, state->h, sizeof(state->h)); + v[8] = UINT_LEAST64_C(0x6A09E667F3BCC908); + v[9] = UINT_LEAST64_C(0xBB67AE8584CAA73B); + v[A] = UINT_LEAST64_C(0x3C6EF372FE94F82B); + v[B] = UINT_LEAST64_C(0xA54FF53A5F1D36F1); + v[C] = UINT_LEAST64_C(0x510E527FADE682D1) ^ state->t[0]; + v[D] = UINT_LEAST64_C(0x9B05688C2B3E6C1F) ^ state->t[1]; + v[E] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B) ^ state->f[0]; + v[F] = UINT_LEAST64_C(0x5BE0CD19137E2179) ^ state->f[1]; + + m[0] = decode_uint64_le(&data[0 * 8]); + m[1] = decode_uint64_le(&data[1 * 8]); + m[2] = decode_uint64_le(&data[2 * 8]); + m[3] = decode_uint64_le(&data[3 * 8]); + m[4] = decode_uint64_le(&data[4 * 8]); + m[5] = decode_uint64_le(&data[5 * 8]); + m[6] = decode_uint64_le(&data[6 * 8]); + m[7] = decode_uint64_le(&data[7 * 8]); + m[8] = decode_uint64_le(&data[8 * 8]); + m[9] = decode_uint64_le(&data[9 * 8]); + m[A] = decode_uint64_le(&data[A * 8]); + m[B] = decode_uint64_le(&data[B * 8]); + m[C] = decode_uint64_le(&data[C * 8]); + m[D] = decode_uint64_le(&data[D * 8]); + m[E] = decode_uint64_le(&data[E * 8]); + m[F] = decode_uint64_le(&data[F * 8]); + +#define G2B(mj, mk, a, b, c, d)\ + a = (a + b + mj) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\ + d = rotate_right(d ^ a, 32);\ + c = (c + d) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\ + b = rotate_right(b ^ c, 24);\ + a = (a + b + mk) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\ + d = rotate_right(d ^ a, 16);\ + c = (c + d) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\ + b = rotate_right(b ^ c, 63) + +#define ROUND2B(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\ + G2B(m[S0], m[S1], v[0], v[4], v[8], v[C]);\ + G2B(m[S2], m[S3], v[1], v[5], v[9], v[D]);\ + G2B(m[S4], m[S5], v[2], v[6], v[A], v[E]);\ + G2B(m[S6], m[S7], v[3], v[7], v[B], v[F]);\ + G2B(m[S8], m[S9], v[0], v[5], v[A], v[F]);\ + G2B(m[SA], m[SB], v[1], v[6], v[B], v[C]);\ + G2B(m[SC], m[SD], v[2], v[7], v[8], v[D]);\ + G2B(m[SE], m[SF], v[3], v[4], v[9], v[E]) + + ROUND2B(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F); + ROUND2B(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3); + ROUND2B(B, 8, C, 0, 5, 2, F, D, A, E, 3, 6, 7, 1, 9, 4); + ROUND2B(7, 9, 3, 1, D, C, B, E, 2, 6, 5, A, 4, 0, F, 8); + ROUND2B(9, 0, 5, 7, 2, 4, A, F, E, 1, B, C, 6, 8, 3, D); + ROUND2B(2, C, 6, A, 0, B, 8, 3, 4, D, 7, 5, F, E, 1, 9); + ROUND2B(C, 5, 1, F, E, D, 4, A, 0, 7, 6, 3, 9, 2, 8, B); + ROUND2B(D, B, 7, E, C, 1, 3, 9, 5, 0, F, 4, 8, 6, 2, A); + ROUND2B(6, F, E, 9, B, 3, 0, 8, C, 2, D, 7, 1, 4, A, 5); + ROUND2B(A, 2, 8, 4, 7, 6, 1, 5, F, B, 9, E, 3, C, D, 0); + ROUND2B(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F); + ROUND2B(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3); + + state->h[0] ^= v[0] ^ v[8]; + state->h[1] ^= v[1] ^ v[9]; + state->h[2] ^= v[2] ^ v[A]; + state->h[3] ^= v[3] ^ v[B]; + state->h[4] ^= v[4] ^ v[C]; + state->h[5] ^= v[5] ^ v[D]; + state->h[6] ^= v[6] ^ v[E]; + state->h[7] ^= v[7] ^ v[F]; +} diff --git a/libblake_internal_blake2s_compress.c b/libblake_internal_blake2s_compress.c new file mode 100644 index 0000000..d3c4066 --- /dev/null +++ b/libblake_internal_blake2s_compress.c @@ -0,0 +1,97 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +#define A 10 +#define B 11 +#define C 12 +#define D 13 +#define E 14 +#define F 15 + +static uint_least32_t +decode_uint32_le(const unsigned char *data) +{ + return (((uint_least32_t)(data[0] & 255)) << 0) | + (((uint_least32_t)(data[1] & 255)) << 8) | + (((uint_least32_t)(data[2] & 255)) << 16) | + (((uint_least32_t)(data[3] & 255)) << 24); +} + +static uint_least32_t +rotate_right(uint_least32_t x, int n) +{ + return ((x >> n) | (x << (32 - n))) & UINT_LEAST32_C(0xFFFFffff); +} + +void +libblake_internal_blake2s_compress(struct libblake_blake2s_state *state, const unsigned char *data) +{ + uint_least32_t v[16], m[16]; + + memcpy(v, state->h, sizeof(state->h)); + v[8] = UINT_LEAST32_C(0x6A09E667); + v[9] = UINT_LEAST32_C(0xBB67AE85); + v[A] = UINT_LEAST32_C(0x3C6EF372); + v[B] = UINT_LEAST32_C(0xA54FF53A); + v[C] = UINT_LEAST32_C(0x510E527F) ^ state->t[0]; + v[D] = UINT_LEAST32_C(0x9B05688C) ^ state->t[1]; + v[E] = UINT_LEAST32_C(0x1F83D9AB) ^ state->f[0]; + v[F] = UINT_LEAST32_C(0x5BE0CD19) ^ state->f[1]; + + m[0] = decode_uint32_le(&data[0 * 4]); + m[1] = decode_uint32_le(&data[1 * 4]); + m[2] = decode_uint32_le(&data[2 * 4]); + m[3] = decode_uint32_le(&data[3 * 4]); + m[4] = decode_uint32_le(&data[4 * 4]); + m[5] = decode_uint32_le(&data[5 * 4]); + m[6] = decode_uint32_le(&data[6 * 4]); + m[7] = decode_uint32_le(&data[7 * 4]); + m[8] = decode_uint32_le(&data[8 * 4]); + m[9] = decode_uint32_le(&data[9 * 4]); + m[A] = decode_uint32_le(&data[A * 4]); + m[B] = decode_uint32_le(&data[B * 4]); + m[C] = decode_uint32_le(&data[C * 4]); + m[D] = decode_uint32_le(&data[D * 4]); + m[E] = decode_uint32_le(&data[E * 4]); + m[F] = decode_uint32_le(&data[F * 4]); + +#define G2S(mj, mk, a, b, c, d)\ + a = (a + b + mj) & UINT_LEAST32_C(0xFFFFffff);\ + d = rotate_right(d ^ a, 16);\ + c = (c + d) & UINT_LEAST32_C(0xFFFFffff);\ + b = rotate_right(b ^ c, 12);\ + a = (a + b + mk) & UINT_LEAST32_C(0xFFFFffff);\ + d = rotate_right(d ^ a, 8);\ + c = (c + d) & UINT_LEAST32_C(0xFFFFffff);\ + b = rotate_right(b ^ c, 7) + +#define ROUND2S(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\ + G2S(m[S0], m[S1], v[0], v[4], v[8], v[C]);\ + G2S(m[S2], m[S3], v[1], v[5], v[9], v[D]);\ + G2S(m[S4], m[S5], v[2], v[6], v[A], v[E]);\ + G2S(m[S6], m[S7], v[3], v[7], v[B], v[F]);\ + G2S(m[S8], m[S9], v[0], v[5], v[A], v[F]);\ + G2S(m[SA], m[SB], v[1], v[6], v[B], v[C]);\ + G2S(m[SC], m[SD], v[2], v[7], v[8], v[D]);\ + G2S(m[SE], m[SF], v[3], v[4], v[9], v[E]) + + ROUND2S(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F); + ROUND2S(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3); + ROUND2S(B, 8, C, 0, 5, 2, F, D, A, E, 3, 6, 7, 1, 9, 4); + ROUND2S(7, 9, 3, 1, D, C, B, E, 2, 6, 5, A, 4, 0, F, 8); + ROUND2S(9, 0, 5, 7, 2, 4, A, F, E, 1, B, C, 6, 8, 3, D); + ROUND2S(2, C, 6, A, 0, B, 8, 3, 4, D, 7, 5, F, E, 1, 9); + ROUND2S(C, 5, 1, F, E, D, 4, A, 0, 7, 6, 3, 9, 2, 8, B); + ROUND2S(D, B, 7, E, C, 1, 3, 9, 5, 0, F, 4, 8, 6, 2, A); + ROUND2S(6, F, E, 9, B, 3, 0, 8, C, 2, D, 7, 1, 4, A, 5); + ROUND2S(A, 2, 8, 4, 7, 6, 1, 5, F, B, 9, E, 3, C, D, 0); + + state->h[0] ^= v[0] ^ v[8]; + state->h[1] ^= v[1] ^ v[9]; + state->h[2] ^= v[2] ^ v[A]; + state->h[3] ^= v[3] ^ v[B]; + state->h[4] ^= v[4] ^ v[C]; + state->h[5] ^= v[5] ^ v[D]; + state->h[6] ^= v[6] ^ v[E]; + state->h[7] ^= v[7] ^ v[F]; +} diff --git a/libblake_internal_blakeb_update.c b/libblake_internal_blakeb_update.c index db4f0b7..a1a88d6 100644 --- a/libblake_internal_blakeb_update.c +++ b/libblake_internal_blakeb_update.c @@ -47,26 +47,26 @@ rotate_right(uint_least64_t x, int n) size_t libblake_internal_blakeb_update(struct libblake_blakeb_state *state, const unsigned char *data, size_t len) { - size_t ret = 0; + size_t off = 0; struct libblake_blakeb_state s; uint_least64_t v[16], m[16]; memcpy(&s, state, sizeof(s)); - for (; len - ret >= 128; ret += 128, data = &data[128]) { - s.t[0] += 1024; - if ((s.t[0] & UINT_LEAST64_C(0xFFFFffffFFFFffff)) < 1024) + for (; len - off >= 128; off += 128, data = &data[128]) { + s.t[0] = (s.t[0] + 1024) & UINT_LEAST64_C(0xFFFFffffFFFFffff); + if (s.t[0] < 1024) s.t[1] = (s.t[1] + 1) & UINT_LEAST64_C(0xFFFFffffFFFFffff); memcpy(v, s.h, sizeof(s.h)); - v[8] = s.s[0] ^ CB0; - v[9] = s.s[1] ^ CB1; - v[10] = s.s[2] ^ CB2; - v[11] = s.s[3] ^ CB3; - v[12] = s.t[0] ^ CB4; - v[13] = s.t[0] ^ CB5; - v[14] = s.t[1] ^ CB6; - v[15] = s.t[1] ^ CB7; + v[8] = s.s[0] ^ CB0; + v[9] = s.s[1] ^ CB1; + v[A] = s.s[2] ^ CB2; + v[B] = s.s[3] ^ CB3; + v[C] = s.t[0] ^ CB4; + v[D] = s.t[0] ^ CB5; + v[E] = s.t[1] ^ CB6; + v[F] = s.t[1] ^ CB7; m[0] = decode_uint64_be(&data[0 * 8]); m[1] = decode_uint64_be(&data[1 * 8]); @@ -97,13 +97,13 @@ libblake_internal_blakeb_update(struct libblake_blakeb_state *state, const unsig #define ROUNDB(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\ GB(m[S0], m[S1], CB##S0, CB##S1, v[0], v[4], v[8], v[C]);\ - GB(m[S2], m[S3], CB##S2, CB##S3, v[1], v[5], v[9], v[D]);\ - GB(m[S4], m[S5], CB##S4, CB##S5, v[2], v[6], v[A], v[E]);\ - GB(m[S6], m[S7], CB##S6, CB##S7, v[3], v[7], v[B], v[F]);\ - GB(m[S8], m[S9], CB##S8, CB##S9, v[0], v[5], v[A], v[F]);\ - GB(m[SA], m[SB], CB##SA, CB##SB, v[1], v[6], v[B], v[C]);\ - GB(m[SC], m[SD], CB##SC, CB##SD, v[2], v[7], v[8], v[D]);\ - GB(m[SE], m[SF], CB##SE, CB##SF, v[3], v[4], v[9], v[E]) + GB(m[S2], m[S3], CB##S2, CB##S3, v[1], v[5], v[9], v[D]);\ + GB(m[S4], m[S5], CB##S4, CB##S5, v[2], v[6], v[A], v[E]);\ + GB(m[S6], m[S7], CB##S6, CB##S7, v[3], v[7], v[B], v[F]);\ + GB(m[S8], m[S9], CB##S8, CB##S9, v[0], v[5], v[A], v[F]);\ + GB(m[SA], m[SB], CB##SA, CB##SB, v[1], v[6], v[B], v[C]);\ + GB(m[SC], m[SD], CB##SC, CB##SD, v[2], v[7], v[8], v[D]);\ + GB(m[SE], m[SF], CB##SE, CB##SF, v[3], v[4], v[9], v[E]) ROUNDB(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F); ROUNDB(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3); @@ -134,5 +134,5 @@ libblake_internal_blakeb_update(struct libblake_blakeb_state *state, const unsig memcpy(state, &s, sizeof(s)); - return ret; + return off; } diff --git a/libblake_internal_blakes_update.c b/libblake_internal_blakes_update.c index 389b5cc..525600a 100644 --- a/libblake_internal_blakes_update.c +++ b/libblake_internal_blakes_update.c @@ -43,26 +43,26 @@ rotate_right(uint_least32_t x, int n) size_t libblake_internal_blakes_update(struct libblake_blakes_state *state, const unsigned char *data, size_t len) { - size_t ret = 0; + size_t off = 0; struct libblake_blakes_state s; uint_least32_t v[16], m[16]; memcpy(&s, state, sizeof(s)); - for (; len - ret >= 64; ret += 64, data = &data[64]) { - s.t[0] += 512; - if ((s.t[0] & UINT_LEAST32_C(0xFFFFffff)) < 512) + for (; len - off >= 64; off += 64, data = &data[64]) { + s.t[0] = (s.t[0] + 512) & UINT_LEAST32_C(0xFFFFffff); + if (s.t[0] < 512) s.t[1] = (s.t[1] + 1) & UINT_LEAST32_C(0xFFFFffff); memcpy(v, s.h, sizeof(s.h)); - v[8] = s.s[0] ^ CS0; - v[9] = s.s[1] ^ CS1; - v[10] = s.s[2] ^ CS2; - v[11] = s.s[3] ^ CS3; - v[12] = s.t[0] ^ CS4; - v[13] = s.t[0] ^ CS5; - v[14] = s.t[1] ^ CS6; - v[15] = s.t[1] ^ CS7; + v[8] = s.s[0] ^ CS0; + v[9] = s.s[1] ^ CS1; + v[A] = s.s[2] ^ CS2; + v[B] = s.s[3] ^ CS3; + v[C] = s.t[0] ^ CS4; + v[D] = s.t[0] ^ CS5; + v[E] = s.t[1] ^ CS6; + v[F] = s.t[1] ^ CS7; m[0] = decode_uint32_be(&data[0 * 4]); m[1] = decode_uint32_be(&data[1 * 4]); @@ -93,13 +93,13 @@ libblake_internal_blakes_update(struct libblake_blakes_state *state, const unsig #define ROUNDS(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\ GS(m[S0], m[S1], CS##S0, CS##S1, v[0], v[4], v[8], v[C]);\ - GS(m[S2], m[S3], CS##S2, CS##S3, v[1], v[5], v[9], v[D]);\ - GS(m[S4], m[S5], CS##S4, CS##S5, v[2], v[6], v[A], v[E]);\ - GS(m[S6], m[S7], CS##S6, CS##S7, v[3], v[7], v[B], v[F]);\ - GS(m[S8], m[S9], CS##S8, CS##S9, v[0], v[5], v[A], v[F]);\ - GS(m[SA], m[SB], CS##SA, CS##SB, v[1], v[6], v[B], v[C]);\ - GS(m[SC], m[SD], CS##SC, CS##SD, v[2], v[7], v[8], v[D]);\ - GS(m[SE], m[SF], CS##SE, CS##SF, v[3], v[4], v[9], v[E]) + GS(m[S2], m[S3], CS##S2, CS##S3, v[1], v[5], v[9], v[D]);\ + GS(m[S4], m[S5], CS##S4, CS##S5, v[2], v[6], v[A], v[E]);\ + GS(m[S6], m[S7], CS##S6, CS##S7, v[3], v[7], v[B], v[F]);\ + GS(m[S8], m[S9], CS##S8, CS##S9, v[0], v[5], v[A], v[F]);\ + GS(m[SA], m[SB], CS##SA, CS##SB, v[1], v[6], v[B], v[C]);\ + GS(m[SC], m[SD], CS##SC, CS##SD, v[2], v[7], v[8], v[D]);\ + GS(m[SE], m[SF], CS##SE, CS##SF, v[3], v[4], v[9], v[E]) ROUNDS(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F); ROUNDS(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3); @@ -128,5 +128,5 @@ libblake_internal_blakes_update(struct libblake_blakes_state *state, const unsig memcpy(state, &s, sizeof(s)); - return ret; + return off; } @@ -123,10 +123,10 @@ check_blake1(void) CHECK_BLAKE512_STR("", "a8cfbbd73726062df0c6864dda65defe58ef0cc52a5625090fa17601e1eecd1b628e94f396ae402a00acc9eab77b4d4c2e852aaaa25a636d80af3fc7913ef5b8"); CHECK_BLAKE512_STR("The quick brown fox jumps over the lazy dog", - "1f7e26f63b6ad25a0896fd978fd050a1766391d2fd0471a77afb975e5034b7ad2d9ccf8dfb47abbbe656e1b82fbc634ba42ce186e8dc5e1ce09a885d41f43451"); + "1f7e26f63b6ad25a0896fd978fd050a1766391d2fd0471a77afb975e5034b7ad2d9ccf8dfb47abbbe656e1b82fbc634ba42ce186e8dc5e1ce09a885d41f43451"); CHECK_BLAKE512_STR("The quick brown fox jumps over the lazy dof", - "a701c2a1f9baabd8b1db6b75aee096900276f0b86dc15d247ecc03937b370324a16a4ffc0c3a85cd63229cfa15c15f4ba6d46ae2e849ed6335e9ff43b764198a"); + "a701c2a1f9baabd8b1db6b75aee096900276f0b86dc15d247ecc03937b370324a16a4ffc0c3a85cd63229cfa15c15f4ba6d46ae2e849ed6335e9ff43b764198a"); bits = 1; #define X(INPUT, EXPECT) CHECK_BLAKE224_BITS(INPUT, bits++, EXPECT); @@ -343,6 +343,146 @@ check_blake1(void) return failed; } +static const char * +digest_blake2s(int length, const void *msg, size_t msglen) +{ + static char hex[1025]; + unsigned char buf[512]; + size_t req; + char *data; + struct libblake_blake2s_state s; + struct libblake_blake2s_params params; + + memset(¶ms, 0, sizeof(params)); + params.digest_len = (uint_least8_t)(length / 8); + params.fanout = 1; + params.depth = 1; + + req = libblake_blake2s_digest_get_required_input_size(msglen); + data = malloc(req); + memcpy(data, msg, msglen); + libblake_blake2s_init(&s, ¶ms, NULL); + libblake_blake2s_digest(&s, data, msglen, (size_t)length / 8, buf); + libblake_encode_hex(buf, (size_t)length / 8, hex, 0); + free(data); + + return hex; +} + +#define CHECK_BLAKE2S_STR(LENGTH, MSG, EXPECTED)\ + failed |= !check_blake2s_(LENGTH, "“"MSG"”", MSG, sizeof(MSG) - 1, EXPECTED) +#define CHECK_BLAKE2S_224_STR(MSG, EXPECTED) CHECK_BLAKE2S_STR(224, MSG, EXPECTED) +#define CHECK_BLAKE2S_256_STR(MSG, EXPECTED) CHECK_BLAKE2S_STR(256, MSG, EXPECTED) + +#if 0 +# define CHECK_BLAKE2S_HEX(LENGTH, MSG, EXPECTED)\ + failed |= !check_blake2s_(LENGTH, "0x"MSG, buf, libblake_decode_hex(MSG, SIZE_MAX, buf, &(int){0}), EXPECTED) +# define CHECK_BLAKE2S_224_HEX(MSG, EXPECTED) CHECK_BLAKE2S_HEX(224, MSG, EXPECTED) +# define CHECK_BLAKE2S_256_HEX(MSG, EXPECTED) CHECK_BLAKE2S_HEX(256, MSG, EXPECTED) +#endif + +static int +check_blake2s_(int length, const char *dispmsg, const void *msg, size_t msglen, const char *expected) +{ + const char *result; + result = digest_blake2s(length, msg, msglen); + if (strcasecmp(result, expected)) { + fprintf(stderr, "BLAKE2s-%i failed for %s:\n", length, dispmsg); + fprintf(stderr, "\tResult: %s\n", result); + fprintf(stderr, "\tExpected: %s\n", expected); + fprintf(stderr, "\n"); + return 0; + } + return 1; +} + +static int +check_blake2s(void) +{ +#if 0 + char buf[1025]; +#endif + int failed = 0; + + CHECK_BLAKE2S_224_STR("", "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"); + CHECK_BLAKE2S_256_STR("", "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"); + + return failed; +} + +static const char * +digest_blake2b(int length, const void *msg, size_t msglen) +{ + static char hex[1025]; + unsigned char buf[512]; + size_t req; + char *data; + struct libblake_blake2b_state s; + struct libblake_blake2b_params params; + + memset(¶ms, 0, sizeof(params)); + params.digest_len = (uint_least8_t)(length / 8); + params.fanout = 1; + params.depth = 1; + + req = libblake_blake2b_digest_get_required_input_size(msglen); + data = malloc(req); + memcpy(data, msg, msglen); + libblake_blake2b_init(&s, ¶ms, NULL); + libblake_blake2b_digest(&s, data, msglen, (size_t)length / 8, buf); + libblake_encode_hex(buf, (size_t)length / 8, hex, 0); + free(data); + + return hex; +} + +#define CHECK_BLAKE2B_STR(LENGTH, MSG, EXPECTED)\ + failed |= !check_blake2b_(LENGTH, "“"MSG"”", MSG, sizeof(MSG) - 1, EXPECTED) +#define CHECK_BLAKE2B_384_STR(MSG, EXPECTED) CHECK_BLAKE2B_STR(384, MSG, EXPECTED) +#define CHECK_BLAKE2B_512_STR(MSG, EXPECTED) CHECK_BLAKE2B_STR(512, MSG, EXPECTED) + +#if 0 +# define CHECK_BLAKE2B_HEX(LENGTH, MSG, EXPECTED)\ + failed |= !check_blake2b_(LENGTH, "0x"MSG, buf, libblake_decode_hex(MSG, SIZE_MAX, buf, &(int){0}), EXPECTED) +# define CHECK_BLAKE2B_384_HEX(MSG, EXPECTED) CHECK_BLAKE2B_HEX(384, MSG, EXPECTED) +# define CHECK_BLAKE2B_512_HEX(MSG, EXPECTED) CHECK_BLAKE2B_HEX(512, MSG, EXPECTED) +#endif + +static int +check_blake2b_(int length, const char *dispmsg, const void *msg, size_t msglen, const char *expected) +{ + const char *result; + result = digest_blake2b(length, msg, msglen); + if (strcasecmp(result, expected)) { + fprintf(stderr, "BLAKE2b-%i failed for %s:\n", length, dispmsg); + fprintf(stderr, "\tResult: %s\n", result); + fprintf(stderr, "\tExpected: %s\n", expected); + fprintf(stderr, "\n"); + return 0; + } + return 1; +} + +static int +check_blake2b(void) +{ +#if 0 + char buf[1025]; +#endif + int failed = 0; + + CHECK_BLAKE2B_384_STR("", "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"); + CHECK_BLAKE2B_512_STR("", "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"); + + CHECK_BLAKE2B_512_STR("The quick brown fox jumps over the lazy dog", + "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918"); + + CHECK_BLAKE2B_512_STR("The quick brown fox jumps over the lazy dof", + "ab6b007747d8068c02e25a6008db8a77c218d94f3b40d2291a7dc8a62090a744c082ea27af01521a102e42f480a31e9844053f456b4b41e8aa78bbe5c12957bb"); + + return failed; +} + int main(void) { @@ -352,6 +492,8 @@ main(void) CHECK_HEX(0, 00, 12, 32, 00, 45, 67, 82, 9a, b0, cd, fe, ff, 80, 08, cc, 28); failed |= check_blake1(); + failed |= check_blake2s(); + failed |= check_blake2b(); return failed; } |